Project

General

Profile

Bug #12324 » interdiff-v2-v3.patch

rhenium (Kazuki Yamaguchi), 05/14/2016 11:20 AM

View differences:

ext/openssl/extconf.rb
Logging::message "=== Checking for OpenSSL features... ===\n"
# compile options
have_func("SSLv2_method")
have_func("SSLv3_method")
# check OPENSSL_NO_{SSL2,SSL3_METHOD} macro: on some environment, these symbols
# exist even if compiled with no-ssl2 or no-ssl3-method.
unless have_macro("OPENSSL_NO_SSL2", "openssl/opensslconf.h")
have_func("SSLv2_method")
end
unless have_macro("OPENSSL_NO_SSL3_METHOD", "openssl/opensslconf.h")
have_func("SSLv3_method")
end
have_func("TLSv1_1_method")
have_func("TLSv1_2_method")
have_func("RAND_egd")
......
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")
OpenSSL.check_func_or_macro("SSL_set_tlsext_host_name", "openssl/ssl.h")
have_struct_member("CRYPTO_THREADID", "ptr", "openssl/crypto.h")
......
have_func("EC_curve_nist2nid")
have_func("X509_REVOKED_dup")
have_func("X509_STORE_CTX_get0_store")
have_func("SSL_is_server");
have_func("SSL_is_server")
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_set_ecdh_auto", "openssl/ssl.h")
ext/openssl/openssl_missing.h
# 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
/* added in 1.0.2 */
#if !defined(HAVE_CRYPTO_MEMCMP)
int CRYPTO_memcmp(const volatile void * volatile in_a, const volatile void * volatile in_b, size_t len);
ext/openssl/ossl_pkey_dh.c
ossl_dh_to_der(VALUE self)
{
EVP_PKEY *pkey;
DH *dh;
unsigned char *p;
long len;
VALUE str;
GetPKeyDH(self, pkey);
if((len = i2d_DHparams(EVP_PKEY_get0_DH(pkey), NULL)) <= 0)
dh = EVP_PKEY_get0_DH(pkey);
if((len = i2d_DHparams(dh, NULL)) <= 0)
ossl_raise(eDHError, NULL);
str = rb_str_new(0, len);
p = (unsigned char *)RSTRING_PTR(str);
if(i2d_DHparams(EVP_PKEY_get0_DH(pkey), &p) < 0)
if(i2d_DHparams(dh, &p) < 0)
ossl_raise(eDHError, NULL);
ossl_str_adjust(str, p);
ext/openssl/ossl_pkey_dsa.c
ossl_dsa_export(int argc, VALUE *argv, VALUE self)
{
EVP_PKEY *pkey;
DSA *dsa;
BIO *out;
const EVP_CIPHER *ciph = NULL;
char *passwd = NULL;
......
if (!(out = BIO_new(BIO_s_mem()))) {
ossl_raise(eDSAError, NULL);
}
if (dsa_has_private(EVP_PKEY_get0_DSA(pkey))) {
if (!PEM_write_bio_DSAPrivateKey(out, EVP_PKEY_get0_DSA(pkey), ciph,
NULL, 0, ossl_pem_passwd_cb, passwd)){
dsa = EVP_PKEY_get0_DSA(pkey);
if (dsa_has_private(dsa)) {
if (!PEM_write_bio_DSAPrivateKey(out, dsa, ciph, NULL, 0,
ossl_pem_passwd_cb, passwd)){
BIO_free(out);
ossl_raise(eDSAError, NULL);
}
} else {
if (!PEM_write_bio_DSA_PUBKEY(out, EVP_PKEY_get0_DSA(pkey))) {
if (!PEM_write_bio_DSA_PUBKEY(out, dsa)) {
BIO_free(out);
ossl_raise(eDSAError, NULL);
}
......
ossl_dsa_to_der(VALUE self)
{
EVP_PKEY *pkey;
DSA *dsa;
int (*i2d_func)_((DSA*, unsigned char**));
unsigned char *p;
long len;
VALUE str;
GetPKeyDSA(self, pkey);
if(dsa_has_private(EVP_PKEY_get0_DSA(pkey)))
dsa = EVP_PKEY_get0_DSA(pkey);
if(dsa_has_private(dsa))
i2d_func = (int(*)_((DSA*,unsigned char**)))i2d_DSAPrivateKey;
else
i2d_func = i2d_DSA_PUBKEY;
if((len = i2d_func(EVP_PKEY_get0_DSA(pkey), NULL)) <= 0)
if((len = i2d_func(dsa, NULL)) <= 0)
ossl_raise(eDSAError, NULL);
str = rb_str_new(0, len);
p = (unsigned char *)RSTRING_PTR(str);
if(i2d_func(EVP_PKEY_get0_DSA(pkey), &p) < 0)
if(i2d_func(dsa, &p) < 0)
ossl_raise(eDSAError, NULL);
ossl_str_adjust(str, p);
ext/openssl/ossl_pkey_rsa.c
ossl_rsa_export(int argc, VALUE *argv, VALUE self)
{
EVP_PKEY *pkey;
RSA *rsa;
BIO *out;
const EVP_CIPHER *ciph = NULL;
char *passwd = NULL;
......
if (!(out = BIO_new(BIO_s_mem()))) {
ossl_raise(eRSAError, NULL);
}
if (rsa_has_private(EVP_PKEY_get0_RSA(pkey))) {
if (!PEM_write_bio_RSAPrivateKey(out, EVP_PKEY_get0_RSA(pkey), ciph,
NULL, 0, ossl_pem_passwd_cb, passwd)) {
rsa = EVP_PKEY_get0_RSA(pkey);
if (rsa_has_private(rsa)) {
if (!PEM_write_bio_RSAPrivateKey(out, rsa, ciph, NULL, 0,
ossl_pem_passwd_cb, passwd)) {
BIO_free(out);
ossl_raise(eRSAError, NULL);
}
} else {
if (!PEM_write_bio_RSA_PUBKEY(out, EVP_PKEY_get0_RSA(pkey))) {
if (!PEM_write_bio_RSA_PUBKEY(out, rsa)) {
BIO_free(out);
ossl_raise(eRSAError, NULL);
}
......
ossl_rsa_to_der(VALUE self)
{
EVP_PKEY *pkey;
RSA *rsa;
int (*i2d_func)_((const RSA*, unsigned char**));
unsigned char *p;
long len;
VALUE str;
GetPKeyRSA(self, pkey);
if(rsa_has_private(EVP_PKEY_get0_RSA(pkey)))
rsa = EVP_PKEY_get0_RSA(pkey);
if(rsa_has_private(rsa))
i2d_func = i2d_RSAPrivateKey;
else
i2d_func = (int (*)(const RSA*, unsigned char**))i2d_RSA_PUBKEY;
if((len = i2d_func(EVP_PKEY_get0_RSA(pkey), NULL)) <= 0)
if((len = i2d_func(rsa, NULL)) <= 0)
ossl_raise(eRSAError, NULL);
str = rb_str_new(0, len);
p = (unsigned char *)RSTRING_PTR(str);
if(i2d_func(EVP_PKEY_get0_RSA(pkey), &p) < 0)
if(i2d_func(rsa, &p) < 0)
ossl_raise(eRSAError, NULL);
ossl_str_adjust(str, p);
return str;
}
#define ossl_rsa_buf_size(pkey) (RSA_size(EVP_PKEY_get0_RSA(pkey))+16)
#define ossl_rsa_buf_size(rsa) (RSA_size(rsa)+16)
/*
* call-seq:
......
ossl_rsa_public_encrypt(int argc, VALUE *argv, VALUE self)
{
EVP_PKEY *pkey;
RSA *rsa;
int buf_len, pad;
VALUE str, buffer, padding;
GetPKeyRSA(self, pkey);
rsa = EVP_PKEY_get0_RSA(pkey);
rb_scan_args(argc, argv, "11", &buffer, &padding);
pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
StringValue(buffer);
str = rb_str_new(0, ossl_rsa_buf_size(pkey));
str = rb_str_new(0, ossl_rsa_buf_size(rsa));
buf_len = RSA_public_encrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer),
(unsigned char *)RSTRING_PTR(str), EVP_PKEY_get0_RSA(pkey),
pad);
(unsigned char *)RSTRING_PTR(str), rsa, pad);
if (buf_len < 0) ossl_raise(eRSAError, NULL);
rb_str_set_len(str, buf_len);
......
ossl_rsa_public_decrypt(int argc, VALUE *argv, VALUE self)
{
EVP_PKEY *pkey;
RSA *rsa;
int buf_len, pad;
VALUE str, buffer, padding;
GetPKeyRSA(self, pkey);
rsa = EVP_PKEY_get0_RSA(pkey);
rb_scan_args(argc, argv, "11", &buffer, &padding);
pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
StringValue(buffer);
str = rb_str_new(0, ossl_rsa_buf_size(pkey));
str = rb_str_new(0, ossl_rsa_buf_size(rsa));
buf_len = RSA_public_decrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer),
(unsigned char *)RSTRING_PTR(str), EVP_PKEY_get0_RSA(pkey),
pad);
(unsigned char *)RSTRING_PTR(str), rsa, pad);
if (buf_len < 0) ossl_raise(eRSAError, NULL);
rb_str_set_len(str, buf_len);
......
ossl_rsa_private_encrypt(int argc, VALUE *argv, VALUE self)
{
EVP_PKEY *pkey;
RSA *rsa;
int buf_len, pad;
VALUE str, buffer, padding;
GetPKeyRSA(self, pkey);
rsa = EVP_PKEY_get0_RSA(pkey);
if (!rsa_is_private(self, EVP_PKEY_get0_RSA(pkey))) {
ossl_raise(eRSAError, "private key needed.");
}
rb_scan_args(argc, argv, "11", &buffer, &padding);
pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
StringValue(buffer);
str = rb_str_new(0, ossl_rsa_buf_size(pkey));
str = rb_str_new(0, ossl_rsa_buf_size(rsa));
buf_len = RSA_private_encrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer),
(unsigned char *)RSTRING_PTR(str), EVP_PKEY_get0_RSA(pkey),
pad);
(unsigned char *)RSTRING_PTR(str), rsa, pad);
if (buf_len < 0) ossl_raise(eRSAError, NULL);
rb_str_set_len(str, buf_len);
......
ossl_rsa_private_decrypt(int argc, VALUE *argv, VALUE self)
{
EVP_PKEY *pkey;
RSA *rsa;
int buf_len, pad;
VALUE str, buffer, padding;
GetPKeyRSA(self, pkey);
if (!rsa_is_private(self, EVP_PKEY_get0_RSA(pkey))) {
rsa = EVP_PKEY_get0_RSA(pkey);
if (!rsa_is_private(self, rsa)) {
ossl_raise(eRSAError, "private key needed.");
}
rb_scan_args(argc, argv, "11", &buffer, &padding);
pad = (argc == 1) ? RSA_PKCS1_PADDING : NUM2INT(padding);
StringValue(buffer);
str = rb_str_new(0, ossl_rsa_buf_size(pkey));
str = rb_str_new(0, ossl_rsa_buf_size(rsa));
buf_len = RSA_private_decrypt(RSTRING_LENINT(buffer), (unsigned char *)RSTRING_PTR(buffer),
(unsigned char *)RSTRING_PTR(str), EVP_PKEY_get0_RSA(pkey),
pad);
(unsigned char *)RSTRING_PTR(str), rsa, pad);
if (buf_len < 0) ossl_raise(eRSAError, NULL);
rb_str_set_len(str, buf_len);
ext/openssl/ossl_x509attr.c
ossl_x509attr_set_value(VALUE self, VALUE value)
{
X509_ATTRIBUTE *attr;
ASN1_TYPE *a1type;
VALUE asn1_value;
int i, asn1_tag;
OSSL_Check_Kind(value, cASN1Data);
asn1_value = rb_attr_get(value, rb_intern("@value"));
asn1_tag = NUM2INT(rb_attr_get(value, rb_intern("@tag")));
if (asn1_tag != V_ASN1_SET)
ossl_raise(eASN1Error, "argument must be a SET");
if (!rb_obj_is_kind_of(asn1_value, rb_cArray))
ossl_raise(eASN1Error, "ASN1::Set has non-array value (bug)");
if(!(a1type = ossl_asn1_get_asn1type(value)))
ossl_raise(eASN1Error, "could not get ASN1_TYPE");
if(ASN1_TYPE_get(a1type) == V_ASN1_SEQUENCE){
ASN1_TYPE_free(a1type);
ossl_raise(eASN1Error, "couldn't set SEQUENCE for attribute value.");
}
GetX509Attr(self, attr);
if (X509_ATTRIBUTE_count(attr)) {
/* populated, reset first */
ASN1_OBJECT *obj = X509_ATTRIBUTE_get0_object(attr);
X509_ATTRIBUTE *new_attr = X509_ATTRIBUTE_new();
if (!new_attr) {
ASN1_TYPE_free(a1type);
if (!new_attr)
ossl_raise(eX509AttrError, NULL);
}
SetX509Attr(self, new_attr);
X509_ATTRIBUTE_set1_object(new_attr, obj);
X509_ATTRIBUTE_free(attr);
attr = new_attr;
}
if (!X509_ATTRIBUTE_set1_data(attr, ASN1_TYPE_get(a1type), a1type->value.ptr, -1)) {
for (i = 0; i < RARRAY_LEN(asn1_value); i++) {
int ret;
ASN1_TYPE *a1type = ossl_asn1_get_asn1type(RARRAY_AREF(asn1_value, i));
ret = X509_ATTRIBUTE_set1_data(attr, ASN1_TYPE_get(a1type), a1type->value.ptr, -1);
ASN1_TYPE_free(a1type);
ossl_raise(eX509AttrError, NULL);
if (!ret)
ossl_raise(eX509AttrError, NULL);
}
ASN1_TYPE_free(a1type);
return value;
}
......
{
X509_ATTRIBUTE *attr;
VALUE str;
long length;
unsigned char *p;
int count;
STACK_OF(ASN1_TYPE) *sk;
int i, count;
/* there is no X509_ATTRIBUTE_get0_set() function.. */
sk = sk_ASN1_TYPE_new_null();
if (!sk)
ossl_raise(eX509AttrError, "sk_new() failed");
GetX509Attr(self, attr);
count = X509_ATTRIBUTE_count(attr);
if (!count) return Qnil;
if (count == 1) {
ASN1_TYPE *a1type = X509_ATTRIBUTE_get0_type(attr, 0);
length = i2d_ASN1_TYPE(a1type, NULL);
str = rb_str_new(0, length);
p = (unsigned char *)RSTRING_PTR(str);
i2d_ASN1_TYPE(a1type, &p);
}
else {
#if defined(i2d_ASN1_SET_OF_ASN1_TYPE)
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);
#else
STACK_OF(ASN1_TYPE) *sk = sk_ASN1_TYPE_new_null();
int i;
if (!sk) ossl_raise(eX509AttrError, "sk_new() failed");
for (i = 0; i < count; i++)
sk_ASN1_TYPE_push(sk, X509_ATTRIBUTE_get0_type(attr, i));
length = i2d_ASN1_SET_ANY(sk, NULL);
str = rb_str_new(0, length);
p = (unsigned char *)RSTRING_PTR(str);
i2d_ASN1_SET_ANY(sk, &p);
sk_ASN1_TYPE_free(sk);
#endif
}
for (i = 0; i < count; i++)
sk_ASN1_TYPE_push(sk, X509_ATTRIBUTE_get0_type(attr, i));
str = rb_str_new(0, i2d_ASN1_SET_ANY(sk, NULL));
p = (unsigned char *)RSTRING_PTR(str);
i2d_ASN1_SET_ANY(sk, &p);
ossl_str_adjust(str, p);
sk_ASN1_TYPE_free(sk);
return rb_funcall(mASN1, rb_intern("decode"), 1, str);
}
......
p = (unsigned char *)RSTRING_PTR(str);
if(i2d_X509_ATTRIBUTE(attr, &p) <= 0)
ossl_raise(eX509AttrError, NULL);
rb_str_set_len(str, p - (unsigned char*)RSTRING_PTR(str));
ossl_str_adjust(str, p);
return str;
}
test/openssl/test_x509attr.rb
# frozen_string_literal: false
require_relative "utils"
if defined?(OpenSSL::TestUtils)
class OpenSSL::TestX509Attribute < Test::Unit::TestCase
def test_new
ef = OpenSSL::X509::ExtensionFactory.new
val = OpenSSL::ASN1::Set.new([OpenSSL::ASN1::Sequence.new([
ef.create_extension("keyUsage", "keyCertSign", true)
])])
attr = OpenSSL::X509::Attribute.new("extReq", val)
assert_equal("extReq", attr.oid)
assert_equal(val.to_der, attr.value.to_der)
end
def test_from_der
# oid: challengePassword, values: Set[UTF8String<"abc123">]
test_der = "\x30\x15\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x09\x07\x31\x08" \
"\x0c\x06\x61\x62\x63\x31\x32\x33".b
attr = OpenSSL::X509::Attribute.new(test_der)
assert_equal(test_der, attr.to_der)
assert_equal("challengePassword", attr.oid)
assert_equal("abc123", attr.value.value[0].value)
end
def test_to_der
ef = OpenSSL::X509::ExtensionFactory.new
val = OpenSSL::ASN1::Set.new([OpenSSL::ASN1::Sequence.new([
ef.create_extension("keyUsage", "keyCertSign", true)
])])
attr = OpenSSL::X509::Attribute.new("extReq", val)
expected = OpenSSL::ASN1::Sequence.new([
OpenSSL::ASN1::ObjectId.new("extReq"),
val
])
assert_equal(expected.to_der, attr.to_der)
end
def test_invalid_value
assert_raise(TypeError) {
OpenSSL::X509::Attribute.new("challengePassword", "1234")
}
end
end
end
(5-5/5)