diff --git a/ChangeLog b/ChangeLog index 076c836299..2f966e6e54 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,52 @@ +Thu Jul 1 11:59:45 2004 GOTOU Yuuzou + + * ext/openssl/extconf.rb: check for EVP_CIPHER_CTX_copy, ENGINE_add, + EVP_CIPHER_CTX_set_padding, EVP_CipherFinal_ex, EVP_CipherInit_ex, + EVP_DigestFinal_ex and EVP_DigestInit_ex. + + * ext/openssl/openssl_missing.c (EVP_CIPHER_CTX_copy): new function. + + * ext/openssl/openssl_missing.h (EVP_DigestInit_ex, EVP_DigestFinal_ex, + EVP_CipherInit_ex, EVP_CipherFinal_ex, HMAC_Init_ex): new macro for + OpenSSL 0.9.6. + + * ext/openssl/ossl_cipher.c (ossl_cipher_encrypt, ossl_cipher_decrypt): + re-implemnt (the arguments for this method is ). + + * ext/openssl/ossl_cipher.c (ossl_cipher_pkcs5_keyivgen): new method + OpenSSL::Cipher::Cipher#pkcs5_keyivgen. it calls EVP_BytesToKey(). + + * ext/openssl/ossl_cipher.c (ossl_cipher_alloc, ossl_cipher_initialize, + ossl_cipher_copy, ossl_cipher_reset ossl_cipher_final, + ossl_cipher_set_key, ossl_cipher_set_iv): replace all EVP_CipherInit + and EVP_CipherFinal into EVP_CipherInit_ex and EVP_CipherFinal_ex. + and EVP_CIPHER_CTX_init should only be called once. + + * ext/openssl/ossl_cipher.c (ossl_cipher_set_key_length): new method + OpenSSL::Cipher::Cipher#key_len=. + + * ext/openssl/ossl_cipher.c (ossl_cipher_set_padding): the type of + argument is changed from integer to boolean. + + * ext/openssl/ossl_cipher.c (ossl_cipher_init_deprecated): new + finction; print warning for Cipher#<<. + + * ext/openssl/ossl_digest.c: replace all EVP_DigestInit and + EVP_DigestFinal into EVP_DigestInit_ex and EVP_DigestFinal_ex. + and EVP_MD_CTX_init should only be called once. + + * ext/openssl/ossl_digest.c (digest_final): should call + EVP_MD_CTX_cleanup to avoid memory leak. + + * ext/openssl/ossl_hmac.c (ossl_hmac_initialize): repalce HMAC_init + into HMAC_init_ex. and HMAC_CTX_init is moved to ossl_hmac_alloc. + + * ext/openssl/ossl_hmac.c (hmac_final): should call + HMAC_CTX_cleanup to avoid memory leak. + + * test/openssl/test_cipher.rb, test/openssl/test_digest.rb, + test/openssl/test_hmac.rb: new file. + Thu Jul 1 04:08:30 2004 GOTOU Yuuzou * ext/openssl/ossl_asn1.c (ossl_i2d_ASN1_TYPE, ossl_ASN1_TYPE_free): diff --git a/MANIFEST b/MANIFEST index f63f3b71b7..d1b5d300df 100644 --- a/MANIFEST +++ b/MANIFEST @@ -777,6 +777,9 @@ test/gdbm/test_gdbm.rb test/logger/test_logger.rb test/monitor/test_monitor.rb test/openssl/ssl_server.rb +test/openssl/test_cipher.rb +test/openssl/test_digest.rb +test/openssl/test_hmac.rb test/openssl/test_ssl.rb test/openssl/test_x509cert.rb test/openssl/test_x509crl.rb diff --git a/ext/openssl/extconf.rb b/ext/openssl/extconf.rb index 47fa722cf0..d587116c82 100644 --- a/ext/openssl/extconf.rb +++ b/ext/openssl/extconf.rb @@ -62,40 +62,54 @@ unless have_header("openssl/conf_api.h") end message "=== Checking for OpenSSL features... ===\n" +have_func("BN_mod_add") +have_func("BN_mod_sqr") +have_func("BN_mod_sub") +have_func("BN_pseudo_rand_range") +have_func("BN_rand_range") +have_func("CONF_get1_default_config_file") +have_func("EVP_CIPHER_CTX_copy") +have_func("EVP_CIPHER_CTX_set_padding") +have_func("EVP_CipherFinal_ex") +have_func("EVP_CipherInit_ex") +have_func("EVP_DigestFinal_ex") +have_func("EVP_DigestInit_ex") +have_func("EVP_MD_CTX_cleanup") +have_func("EVP_MD_CTX_create") +have_func("EVP_MD_CTX_destroy") +have_func("EVP_MD_CTX_init") +have_func("HMAC_CTX_cleanup") have_func("HMAC_CTX_copy") +have_func("HMAC_CTX_init") +have_func("PEM_def_callback") +have_func("X509V3_set_nconf") +have_func("X509_CRL_add0_revoked") +have_func("X509_CRL_set_issuer_name") +have_func("X509_CRL_set_version") +have_func("X509_CRL_sort") have_func("X509_STORE_get_ex_data") have_func("X509_STORE_set_ex_data") -have_func("EVP_MD_CTX_create") -have_func("EVP_MD_CTX_cleanup") -have_func("EVP_MD_CTX_destroy") -have_func("PEM_def_callback") -have_func("EVP_MD_CTX_init") -have_func("HMAC_CTX_init") -have_func("HMAC_CTX_cleanup") -have_func("X509_CRL_set_version") -have_func("X509_CRL_set_issuer_name") -have_func("X509_CRL_sort") -have_func("X509_CRL_add0_revoked") -have_func("CONF_get1_default_config_file") -have_func("BN_mod_sqr") -have_func("BN_mod_add") -have_func("BN_mod_sub") -have_func("BN_rand_range") -have_func("BN_pseudo_rand_range") -have_func("CONF_get1_default_config_file") -have_func("X509V3_set_nconf") if try_compile("#define FOO(a, ...) foo(a, ##__VA_ARGS__)\n int x(){FOO(1);FOO(1,2);FOO(1,2,3);}\n") $defs.push("-DHAVE_VA_ARGS_MACRO") end if have_header("openssl/engine.h") + have_func("ENGINE_add") have_func("ENGINE_load_builtin_engines") have_func("ENGINE_load_openbsd_dev_crypto") have_func("ENGINE_get_digest") have_func("ENGINE_get_cipher") have_func("ENGINE_cleanup") end -have_header("openssl/ocsp.h") +if try_compile(< +#if OPENSSL_VERSION_NUMBER < 0x00907000L +# error "OpenSSL version is less than 0.9.7." +#endif +SRC + have_header("openssl/ocsp.h") +end have_struct_member("EVP_CIPHER_CTX", "flags", "openssl/evp.h") +have_struct_member("EVP_CIPHER_CTX", "engine", "openssl/evp.h") have_struct_member("X509_ATTRIBUTE", "single", "openssl/x509.h") message "=== Checking done. ===\n" diff --git a/ext/openssl/openssl_missing.c b/ext/openssl/openssl_missing.c index 0c0be5fc1f..dfa5f90012 100644 --- a/ext/openssl/openssl_missing.c +++ b/ext/openssl/openssl_missing.c @@ -105,6 +105,29 @@ HMAC_CTX_cleanup(HMAC_CTX *ctx) } #endif +#if !defined(HAVE_EVP_CIPHER_CTX_COPY) +/* + * this function does not exist in OpenSSL yet... or ever?. + * a future version may break this function. + * tested on 0.9.7d. + */ +int +EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, EVP_CIPHER_CTX *in) +{ + memcpy(out, in, sizeof(EVP_CIPHER_CTX)); + +#if defined(HAVE_ENGINE_ADD) && defined(HAVE_ST_ENGINE) + if (in->engine) ENGINE_add(out->engine); + if (in->cipher_data) { + out->cipher_data = OPENSSL_malloc(in->cipher->ctx_size); + memcpy(out->cipher_data, in->cipher_data, in->cipher->ctx_size); + } +#endif + + return 1; +} +#endif + #if !defined(HAVE_X509_CRL_SET_VERSION) int X509_CRL_set_version(X509_CRL *x, long version) diff --git a/ext/openssl/openssl_missing.h b/ext/openssl/openssl_missing.h index 7a755f79b5..2a082f3fe0 100644 --- a/ext/openssl/openssl_missing.h +++ b/ext/openssl/openssl_missing.h @@ -56,13 +56,33 @@ extern "C" { (char *(*)())d2i_PKCS7_RECIP_INFO, (char *)ri) #endif +void HMAC_CTX_init(HMAC_CTX *ctx); int HMAC_CTX_copy(HMAC_CTX *out, HMAC_CTX *in); -void *X509_STORE_get_ex_data(X509_STORE *str, int idx); -int X509_STORE_set_ex_data(X509_STORE *str, int idx, void *data); +void HMAC_CTX_cleanup(HMAC_CTX *ctx); + EVP_MD_CTX *EVP_MD_CTX_create(void); +void EVP_MD_CTX_init(EVP_MD_CTX *ctx); int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx); void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx); +#if !defined(HAVE_EVP_CIPHER_CTX_COPY) +int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, EVP_CIPHER_CTX *in); +#endif + +#if !defined(HAVE_EVP_DIGESTINIT_EX) +# define EVP_DigestInit_ex(ctx, md, engine) EVP_DigestInit(ctx, md) +#endif +#if !defined(HAVE_EVP_DIGESTFINAL_EX) +# define EVP_DigestFinal_ex(ctx, buf, len) EVP_DigestFinal(ctx, buf, len) +#endif + +#if !defined(HAVE_EVP_CIPHERINIT_EX) +# define EVP_CipherInit_ex(ctx, type, impl, key, iv, enc) EVP_CipherInit(ctx, type, key, iv, enc) +#endif +#if !defined(HAVE_EVP_CIPHERFINAL_EX) +# define EVP_CipherFinal_ex(ctx, outm, outl) EVP_CipherFinal(ctx, outm, outl) +#endif + #if !defined(EVP_CIPHER_name) # define EVP_CIPHER_name(e) OBJ_nid2sn(EVP_CIPHER_nid(e)) #endif @@ -71,9 +91,9 @@ void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx); # define EVP_MD_name(e) OBJ_nid2sn(EVP_MD_type(e)) #endif -void EVP_MD_CTX_init(EVP_MD_CTX *ctx); -void HMAC_CTX_init(HMAC_CTX *ctx); -void HMAC_CTX_cleanup(HMAC_CTX *ctx); +#if !defined(HAVE_EVP_HMAC_INIT_EX) +# define HMAC_Init_ex(ctx, key, len, digest, engine) HMAC_Init(ctx, key, len, digest) +#endif #if !defined(PKCS7_is_detached) # define PKCS7_is_detached(p7) (PKCS7_type_is_signed(p7) && PKCS7_get_detached(p7)) @@ -83,6 +103,8 @@ void HMAC_CTX_cleanup(HMAC_CTX *ctx); # define PKCS7_type_is_encrypted(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_encrypted) #endif +void *X509_STORE_get_ex_data(X509_STORE *str, int idx); +int X509_STORE_set_ex_data(X509_STORE *str, int idx, void *data); int X509_CRL_set_version(X509_CRL *x, long version); int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name); int X509_CRL_sort(X509_CRL *c); diff --git a/ext/openssl/ossl_cipher.c b/ext/openssl/ossl_cipher.c index 93b3f6ccf9..6e238189d1 100644 --- a/ext/openssl/ossl_cipher.c +++ b/ext/openssl/ossl_cipher.c @@ -54,7 +54,7 @@ ossl_cipher_new(const EVP_CIPHER *cipher) ret = ossl_cipher_alloc(cCipher); GetCipher(ret, ctx); EVP_CIPHER_CTX_init(ctx); - if (EVP_CipherInit(ctx, cipher, NULL, NULL, -1) != 1) + if (EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, -1) != 1) ossl_raise(eCipherError, NULL); return ret; @@ -79,6 +79,7 @@ ossl_cipher_alloc(VALUE klass) VALUE obj; MakeCipher(obj, klass, ctx); + EVP_CIPHER_CTX_init(ctx); return obj; } @@ -97,9 +98,8 @@ ossl_cipher_initialize(VALUE self, VALUE str) if (!(cipher = EVP_get_cipherbyname(name))) { ossl_raise(rb_eRuntimeError, "Unsupported cipher algorithm (%s).", name); } - EVP_CIPHER_CTX_init(ctx); - if (EVP_CipherInit(ctx, cipher, NULL, NULL, -1) != 1) - ossl_raise(eCipherError, NULL); + if (EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, -1) != 1) + ossl_raise(eCipherError, NULL); return self; } @@ -113,8 +113,8 @@ ossl_cipher_copy(VALUE self, VALUE other) GetCipher(self, ctx1); SafeGetCipher(other, ctx2); - - memcpy(ctx1, ctx2, sizeof(EVP_CIPHER_CTX)); + if (EVP_CIPHER_CTX_copy(ctx1, ctx2) != 1) + ossl_raise(eCipherError, NULL); return self; } @@ -125,107 +125,92 @@ ossl_cipher_reset(VALUE self) EVP_CIPHER_CTX *ctx; GetCipher(self, ctx); - if (EVP_CipherInit(ctx, NULL, NULL, NULL, -1) != 1) + if (EVP_CipherInit_ex(ctx, NULL, NULL, NULL, NULL, -1) != 1) ossl_raise(eCipherError, NULL); return self; } static VALUE -ossl_cipher_encrypt(int argc, VALUE *argv, VALUE self) +ossl_cipher_init(int argc, VALUE *argv, VALUE self, int mode) { EVP_CIPHER_CTX *ctx; - unsigned char iv[EVP_MAX_IV_LENGTH], key[EVP_MAX_KEY_LENGTH]; + unsigned char key[EVP_MAX_KEY_LENGTH], *p_key = NULL; + unsigned char iv[EVP_MAX_IV_LENGTH], *p_iv = NULL; VALUE pass, init_v; GetCipher(self, ctx); - - rb_scan_args(argc, argv, "02", &pass, &init_v); - - if (NIL_P(init_v)) { + if(rb_scan_args(argc, argv, "02", &pass, &init_v) > 0){ /* - * TODO: - * random IV generation! - */ - memcpy(iv, "OpenSSL for Ruby rulez!", sizeof(iv)); - /* - RAND_add(data,i,0); where from take data? - if (RAND_pseudo_bytes(iv, 8) < 0) { - ossl_raise(eCipherError, NULL); - } - */ - } - else { - init_v = rb_obj_as_string(init_v); - if (EVP_MAX_IV_LENGTH > RSTRING(init_v)->len) { - memset(iv, 0, EVP_MAX_IV_LENGTH); - memcpy(iv, RSTRING(init_v)->ptr, RSTRING(init_v)->len); - } - else { - memcpy(iv, RSTRING(init_v)->ptr, sizeof(iv)); + * oops. this code mistakes salt for IV. + * We deprecated the arguments for this method, but we decided + * keeping this behaviour for backward compatibility. + */ + StringValue(pass); + if (NIL_P(init_v)) memcpy(iv, "OpenSSL for Ruby rulez!", sizeof(iv)); + else{ + char *cname = rb_class2name(rb_obj_class(self)); + rb_warning("key derivation by %s#encrypt is deprecated; " + "use %s::pkcs5_keyivgen instead", cname, cname); + StringValue(init_v); + if (EVP_MAX_IV_LENGTH > RSTRING(init_v)->len) { + memset(iv, 0, EVP_MAX_IV_LENGTH); + memcpy(iv, RSTRING(init_v)->ptr, RSTRING(init_v)->len); + } + else memcpy(iv, RSTRING(init_v)->ptr, sizeof(iv)); } + EVP_BytesToKey(EVP_CIPHER_CTX_cipher(ctx), EVP_md5(), iv, + RSTRING(pass)->ptr, RSTRING(pass)->len, 1, key, NULL); + p_key = key; + p_iv = iv; } - - if (EVP_CipherInit(ctx, NULL, NULL, NULL, 1) != 1) { - ossl_raise(eCipherError, NULL); - } - - if (!NIL_P(pass)) { - StringValue(pass); - - EVP_BytesToKey(EVP_CIPHER_CTX_cipher(ctx), EVP_md5(), iv, - RSTRING(pass)->ptr, RSTRING(pass)->len, 1, key, NULL); - if (EVP_CipherInit(ctx, NULL, key, iv, -1) != 1) { - ossl_raise(eCipherError, NULL); - } + if (EVP_CipherInit_ex(ctx, NULL, NULL, p_key, p_iv, mode) != 1) { + ossl_raise(eCipherError, NULL); } return self; } +static VALUE +ossl_cipher_encrypt(int argc, VALUE *argv, VALUE self) +{ + return ossl_cipher_init(argc, argv, self, 1); +} + static VALUE ossl_cipher_decrypt(int argc, VALUE *argv, VALUE self) +{ + return ossl_cipher_init(argc, argv, self, 0); +} + +static VALUE +ossl_cipher_pkcs5_keyivgen(int argc, VALUE *argv, VALUE self) { EVP_CIPHER_CTX *ctx; - unsigned char iv[EVP_MAX_IV_LENGTH], key[EVP_MAX_KEY_LENGTH]; - VALUE pass, init_v; - + const EVP_MD *digest; + VALUE vpass, vsalt, viter, vdigest; + unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH], *salt = NULL; + int iter; + GetCipher(self, ctx); - rb_scan_args(argc, argv, "02", &pass, &init_v); - - if (NIL_P(init_v)) { - /* - * TODO: - * random IV generation! - */ - memcpy(iv, "OpenSSL for Ruby rulez!", EVP_MAX_IV_LENGTH); - } - else { - init_v = rb_obj_as_string(init_v); - if (EVP_MAX_IV_LENGTH > RSTRING(init_v)->len) { - memset(iv, 0, EVP_MAX_IV_LENGTH); - memcpy(iv, RSTRING(init_v)->ptr, RSTRING(init_v)->len); - } - else { - memcpy(iv, RSTRING(init_v)->ptr, EVP_MAX_IV_LENGTH); - } + rb_scan_args(argc, argv, "13", &vpass, &vsalt, &viter, &vdigest); + StringValue(vpass); + if(!NIL_P(vsalt)){ + StringValue(vsalt); + if(RSTRING(vsalt)->len != PKCS5_SALT_LEN) + rb_raise(eCipherError, "salt must be an 8-octet string."); + salt = RSTRING(vsalt)->ptr; } + iter = NIL_P(viter) ? 2048 : NUM2INT(viter); + digest = NIL_P(vdigest) ? EVP_md5() : GetDigestPtr(vdigest); + EVP_BytesToKey(EVP_CIPHER_CTX_cipher(ctx), digest, salt, + RSTRING(vpass)->ptr, RSTRING(vpass)->len, iter, key, iv); + if (EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, -1) != 1) + ossl_raise(eCipherError, NULL); + OPENSSL_cleanse(key, sizeof key); + OPENSSL_cleanse(iv, sizeof iv); - if (EVP_CipherInit(ctx, NULL, NULL, NULL, 0) != 1) { - ossl_raise(eCipherError, NULL); - } - - if (!NIL_P(pass)) { - StringValue(pass); - - EVP_BytesToKey(EVP_CIPHER_CTX_cipher(ctx), EVP_md5(), iv, - RSTRING(pass)->ptr, RSTRING(pass)->len, 1, key, NULL); - if (EVP_CipherInit(ctx, NULL, key, iv, -1) != 1) { - ossl_raise(eCipherError, NULL); - } - } - - return self; + return Qnil; } static VALUE @@ -250,6 +235,16 @@ ossl_cipher_update(VALUE self, VALUE data) return str; } +static VALUE +ossl_cipher_update_deprecated(VALUE self, VALUE data) +{ + char *cname; + + cname = rb_class2name(rb_obj_class(self)); + rb_warning("%s#<< is deprecated; use %s#update instead", cname, cname); + return ossl_cipher_update(self, data); +} + static VALUE ossl_cipher_final(VALUE self) { @@ -259,7 +254,7 @@ ossl_cipher_final(VALUE self) GetCipher(self, ctx); str = rb_str_new(0, EVP_CIPHER_CTX_block_size(ctx)); - if (!EVP_CipherFinal(ctx, RSTRING(str)->ptr, &out_len)) + if (!EVP_CipherFinal_ex(ctx, RSTRING(str)->ptr, &out_len)) ossl_raise(eCipherError, NULL); assert(out_len <= RSTRING(str)->len); RSTRING(str)->len = out_len; @@ -289,7 +284,7 @@ ossl_cipher_set_key(VALUE self, VALUE key) if (RSTRING(key)->len < EVP_CIPHER_CTX_key_length(ctx)) ossl_raise(eCipherError, "key length too short"); - if (EVP_CipherInit(ctx, NULL, RSTRING(key)->ptr, NULL, -1) != 1) + if (EVP_CipherInit_ex(ctx, NULL, NULL, RSTRING(key)->ptr, NULL, -1) != 1) ossl_raise(eCipherError, NULL); return key; @@ -306,22 +301,35 @@ ossl_cipher_set_iv(VALUE self, VALUE iv) if (RSTRING(iv)->len < EVP_CIPHER_CTX_iv_length(ctx)) ossl_raise(eCipherError, "iv length too short"); - if (EVP_CipherInit(ctx, NULL, NULL, RSTRING(iv)->ptr, -1) != 1) - ossl_raise(eCipherError, NULL); + if (EVP_CipherInit_ex(ctx, NULL, NULL, NULL, RSTRING(iv)->ptr, -1) != 1) + ossl_raise(eCipherError, NULL); return iv; } +static VALUE +ossl_cipher_set_key_length(VALUE self, VALUE key_length) +{ + EVP_CIPHER_CTX *ctx; + + GetCipher(self, ctx); + if (EVP_CIPHER_CTX_set_key_length(ctx, NUM2INT(key_length)) != 1) + ossl_raise(eCipherError, NULL); + + return key_length; +} + static VALUE ossl_cipher_set_padding(VALUE self, VALUE padding) { -#if defined(HAVE_ST_FLAGS) +#if defined(HAVE_EVP_CIPHER_CTX_SET_PADDING) EVP_CIPHER_CTX *ctx; GetCipher(self, ctx); - - if (EVP_CIPHER_CTX_set_padding(ctx, NUM2INT(padding)) != 1) - ossl_raise(eCipherError, NULL); + if(rb_obj_is_kind_of(padding, rb_cInteger)) + padding = NUM2INT(padding) ? Qtrue : Qfalse; + if (EVP_CIPHER_CTX_set_padding(ctx, RTEST(padding)) != 1) + ossl_raise(eCipherError, NULL); #else rb_notimplement(); #endif @@ -351,32 +359,21 @@ Init_ossl_cipher(void) cCipher = rb_define_class_under(mCipher, "Cipher", rb_cObject); rb_define_alloc_func(cCipher, ossl_cipher_alloc); - rb_define_method(cCipher, "initialize", ossl_cipher_initialize, 1); - rb_define_copy_func(cCipher, ossl_cipher_copy); - + rb_define_method(cCipher, "initialize", ossl_cipher_initialize, 1); rb_define_method(cCipher, "reset", ossl_cipher_reset, 0); - rb_define_method(cCipher, "encrypt", ossl_cipher_encrypt, -1); rb_define_method(cCipher, "decrypt", ossl_cipher_decrypt, -1); + rb_define_method(cCipher, "pkcs5_keyivgen", ossl_cipher_pkcs5_keyivgen, -1); rb_define_method(cCipher, "update", ossl_cipher_update, 1); - rb_define_alias(cCipher, "<<", "update"); + rb_define_method(cCipher, "<<", ossl_cipher_update_deprecated, 1); rb_define_method(cCipher, "final", ossl_cipher_final, 0); - rb_define_method(cCipher, "name", ossl_cipher_name, 0); - rb_define_method(cCipher, "key=", ossl_cipher_set_key, 1); + rb_define_method(cCipher, "key_len=", ossl_cipher_set_key_length, 1); rb_define_method(cCipher, "key_len", ossl_cipher_key_length, 0); -/* - * TODO - * int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *x, int keylen); - */ rb_define_method(cCipher, "iv=", ossl_cipher_set_iv, 1); rb_define_method(cCipher, "iv_len", ossl_cipher_iv_length, 0); - rb_define_method(cCipher, "block_size", ossl_cipher_block_size, 0); - rb_define_method(cCipher, "padding=", ossl_cipher_set_padding, 1); - -} /* Init_ossl_cipher */ - +} diff --git a/ext/openssl/ossl_digest.c b/ext/openssl/ossl_digest.c index b117ddd30d..8ad9f01dc4 100644 --- a/ext/openssl/ossl_digest.c +++ b/ext/openssl/ossl_digest.c @@ -52,7 +52,7 @@ ossl_digest_new(const EVP_MD *md) ret = ossl_digest_alloc(cDigest); GetDigest(ret, ctx); EVP_MD_CTX_init(ctx); - EVP_DigestInit(ctx, md); + EVP_DigestInit_ex(ctx, md, NULL); return ret; } @@ -69,6 +69,7 @@ ossl_digest_alloc(VALUE klass) ctx = EVP_MD_CTX_create(); if (ctx == NULL) ossl_raise(rb_eRuntimeError, "EVP_MD_CTX_create() failed"); + EVP_MD_CTX_init(ctx); obj = Data_Wrap_Struct(klass, 0, EVP_MD_CTX_destroy, ctx); return obj; @@ -94,8 +95,7 @@ ossl_digest_initialize(int argc, VALUE *argv, VALUE self) if (!md) { ossl_raise(rb_eRuntimeError, "Unsupported digest algorithm (%s).", name); } - EVP_MD_CTX_init(ctx); - EVP_DigestInit(ctx, md); + EVP_DigestInit_ex(ctx, md, NULL); if (!NIL_P(data)) return ossl_digest_update(self, data); return self; @@ -124,7 +124,7 @@ ossl_digest_reset(VALUE self) EVP_MD_CTX *ctx; GetDigest(self, ctx); - EVP_DigestInit(ctx, EVP_MD_CTX_md(ctx)); + EVP_DigestInit_ex(ctx, EVP_MD_CTX_md(ctx), NULL); return self; } @@ -150,9 +150,10 @@ digest_final(EVP_MD_CTX *ctx, char **buf, int *buf_len) ossl_raise(eDigestError, NULL); } if (!(*buf = OPENSSL_malloc(EVP_MD_CTX_size(&final)))) { + EVP_MD_CTX_cleanup(&final); ossl_raise(eDigestError, "Cannot allocate mem for digest"); } - EVP_DigestFinal(&final, *buf, buf_len); + EVP_DigestFinal_ex(&final, *buf, buf_len); EVP_MD_CTX_cleanup(&final); } diff --git a/ext/openssl/ossl_hmac.c b/ext/openssl/ossl_hmac.c index 0b4d8d9b54..fb3d0a6a8f 100644 --- a/ext/openssl/ossl_hmac.c +++ b/ext/openssl/ossl_hmac.c @@ -41,8 +41,8 @@ VALUE eHMACError; static void ossl_hmac_free(HMAC_CTX *ctx) { - HMAC_CTX_cleanup(ctx); - free(ctx); + HMAC_CTX_cleanup(ctx); + free(ctx); } static VALUE @@ -52,6 +52,7 @@ ossl_hmac_alloc(VALUE klass) VALUE obj; MakeHMAC(obj, klass, ctx); + HMAC_CTX_init(ctx); return obj; } @@ -63,8 +64,8 @@ ossl_hmac_initialize(VALUE self, VALUE key, VALUE digest) GetHMAC(self, ctx); StringValue(key); - HMAC_CTX_init(ctx); - HMAC_Init(ctx, RSTRING(key)->ptr, RSTRING(key)->len, GetDigestPtr(digest)); + HMAC_Init_ex(ctx, RSTRING(key)->ptr, RSTRING(key)->len, + GetDigestPtr(digest), NULL); return self; } @@ -107,6 +108,7 @@ hmac_final(HMAC_CTX *ctx, char **buf, int *buf_len) ossl_raise(eHMACError, NULL); } if (!(*buf = OPENSSL_malloc(HMAC_size(&final)))) { + HMAC_CTX_cleanup(&final); OSSL_Debug("Allocating %d mem", HMAC_size(&final)); ossl_raise(eHMACError, "Cannot allocate memory for hmac"); }