* ext/openssl/ossl.c/.h: Added ossl_x509_name_sk2ary.
* ext/openssl/ossl.c: Replaced ossl_x509_ary2k by generic macro to simplify future conversions. * ext/openssl/ossl_ssl.c: Implement SSLSocket#client_ca. * test/openssl/test_ssl.rb: Add test for SSLSocket#client_ca. Thanks to Ippei Obayashi for providing the patch! [ Ruby 1.9 - Feature #4481 ] [ruby-core:35461] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@32337 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
c4becf8aaf
commit
1dcd4b325e
10
ChangeLog
10
ChangeLog
@ -1,3 +1,13 @@
|
|||||||
|
Thu Jun 30 23:43:30 2011 Martin Bosslet <Martin.Bosslet@googlemail.com>
|
||||||
|
|
||||||
|
* ext/openssl/ossl.c/.h: Added ossl_x509_name_sk2ary.
|
||||||
|
* ext/openssl/ossl.c: Replaced ossl_x509_ary2k by generic macro to
|
||||||
|
simplify future conversions.
|
||||||
|
* ext/openssl/ossl_ssl.c: Implement SSLSocket#client_ca.
|
||||||
|
* test/openssl/test_ssl.rb: Add test for SSLSocket#client_ca.
|
||||||
|
Thanks to Ippei Obayashi for providing the patch!
|
||||||
|
[ Ruby 1.9 - Feature #4481 ] [ruby-core:35461]
|
||||||
|
|
||||||
Thu Jun 30 22:38:58 2011 Koichi Sasada <ko1@atdot.net>
|
Thu Jun 30 22:38:58 2011 Koichi Sasada <ko1@atdot.net>
|
||||||
|
|
||||||
* benchmark/bm_vm2_defined_method.rb: added to measure performance of
|
* benchmark/bm_vm2_defined_method.rb: added to measure performance of
|
||||||
|
@ -47,48 +47,53 @@ string2hex(const unsigned char *buf, int buf_len, char **hexbuf, int *hexbuf_len
|
|||||||
/*
|
/*
|
||||||
* Data Conversion
|
* Data Conversion
|
||||||
*/
|
*/
|
||||||
STACK_OF(X509) *
|
#define OSSL_IMPL_ARY2SK(name, type, expected_class, dup) \
|
||||||
ossl_x509_ary2sk0(VALUE ary)
|
STACK_OF(type) * \
|
||||||
{
|
ossl_##name##_ary2sk0(VALUE ary) \
|
||||||
STACK_OF(X509) *sk;
|
{ \
|
||||||
VALUE val;
|
STACK_OF(type) *sk; \
|
||||||
X509 *x509;
|
VALUE val; \
|
||||||
int i;
|
type *x; \
|
||||||
|
int i; \
|
||||||
Check_Type(ary, T_ARRAY);
|
\
|
||||||
sk = sk_X509_new_null();
|
Check_Type(ary, T_ARRAY); \
|
||||||
if (!sk) ossl_raise(eOSSLError, NULL);
|
sk = sk_##type##_new_null(); \
|
||||||
|
if (!sk) ossl_raise(eOSSLError, NULL); \
|
||||||
for (i = 0; i < RARRAY_LEN(ary); i++) {
|
\
|
||||||
val = rb_ary_entry(ary, i);
|
for (i = 0; i < RARRAY_LEN(ary); i++) { \
|
||||||
if (!rb_obj_is_kind_of(val, cX509Cert)) {
|
val = rb_ary_entry(ary, i); \
|
||||||
sk_X509_pop_free(sk, X509_free);
|
if (!rb_obj_is_kind_of(val, expected_class)) { \
|
||||||
ossl_raise(eOSSLError, "object not X509 cert in array");
|
sk_##type##_pop_free(sk, type##_free); \
|
||||||
}
|
ossl_raise(eOSSLError, "object in array not" \
|
||||||
x509 = DupX509CertPtr(val); /* NEED TO DUP */
|
" of class ##type##"); \
|
||||||
sk_X509_push(sk, x509);
|
} \
|
||||||
}
|
x = dup(val); /* NEED TO DUP */ \
|
||||||
return sk;
|
sk_##type##_push(sk, x); \
|
||||||
}
|
} \
|
||||||
|
return sk; \
|
||||||
STACK_OF(X509) *
|
} \
|
||||||
ossl_protect_x509_ary2sk(VALUE ary, int *status)
|
\
|
||||||
{
|
STACK_OF(type) * \
|
||||||
return (STACK_OF(X509)*)rb_protect((VALUE(*)_((VALUE)))ossl_x509_ary2sk0,
|
ossl_protect_##name##_ary2sk(VALUE ary, int *status) \
|
||||||
ary, status);
|
{ \
|
||||||
}
|
return (STACK_OF(type)*)rb_protect( \
|
||||||
|
(VALUE(*)_((VALUE)))ossl_##name##_ary2sk0, \
|
||||||
STACK_OF(X509) *
|
ary, \
|
||||||
ossl_x509_ary2sk(VALUE ary)
|
status); \
|
||||||
{
|
} \
|
||||||
STACK_OF(X509) *sk;
|
\
|
||||||
int status = 0;
|
STACK_OF(type) * \
|
||||||
|
ossl_##name##_ary2sk(VALUE ary) \
|
||||||
sk = ossl_protect_x509_ary2sk(ary, &status);
|
{ \
|
||||||
if(status) rb_jump_tag(status);
|
STACK_OF(type) *sk; \
|
||||||
|
int status = 0; \
|
||||||
return sk;
|
\
|
||||||
|
sk = ossl_protect_##name##_ary2sk(ary, &status); \
|
||||||
|
if (status) rb_jump_tag(status); \
|
||||||
|
\
|
||||||
|
return sk; \
|
||||||
}
|
}
|
||||||
|
OSSL_IMPL_ARY2SK(x509, X509, cX509Cert, DupX509CertPtr)
|
||||||
|
|
||||||
#define OSSL_IMPL_SK2ARY(name, type) \
|
#define OSSL_IMPL_SK2ARY(name, type) \
|
||||||
VALUE \
|
VALUE \
|
||||||
@ -117,6 +122,7 @@ ossl_##name##_sk2ary(STACK_OF(type) *sk) \
|
|||||||
}
|
}
|
||||||
OSSL_IMPL_SK2ARY(x509, X509)
|
OSSL_IMPL_SK2ARY(x509, X509)
|
||||||
OSSL_IMPL_SK2ARY(x509crl, X509_CRL)
|
OSSL_IMPL_SK2ARY(x509crl, X509_CRL)
|
||||||
|
OSSL_IMPL_SK2ARY(x509name, X509_NAME)
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
ossl_str_new(int size)
|
ossl_str_new(int size)
|
||||||
|
@ -126,6 +126,7 @@ STACK_OF(X509) *ossl_x509_ary2sk(VALUE);
|
|||||||
STACK_OF(X509) *ossl_protect_x509_ary2sk(VALUE,int*);
|
STACK_OF(X509) *ossl_protect_x509_ary2sk(VALUE,int*);
|
||||||
VALUE ossl_x509_sk2ary(STACK_OF(X509) *certs);
|
VALUE ossl_x509_sk2ary(STACK_OF(X509) *certs);
|
||||||
VALUE ossl_x509crl_sk2ary(STACK_OF(X509_CRL) *crl);
|
VALUE ossl_x509crl_sk2ary(STACK_OF(X509_CRL) *crl);
|
||||||
|
VALUE ossl_x509name_sk2ary(STACK_OF(X509_NAME) *names);
|
||||||
VALUE ossl_buf2str(char *buf, int len);
|
VALUE ossl_buf2str(char *buf, int len);
|
||||||
#define ossl_str_adjust(str, p) \
|
#define ossl_str_adjust(str, p) \
|
||||||
do{\
|
do{\
|
||||||
|
@ -1643,6 +1643,33 @@ ossl_ssl_get_verify_result(VALUE self)
|
|||||||
return INT2FIX(SSL_get_verify_result(ssl));
|
return INT2FIX(SSL_get_verify_result(ssl));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* call-seq:
|
||||||
|
* ssl.client_ca => [x509name, ...]
|
||||||
|
*
|
||||||
|
* Returns the list of client CAs. Please note that in contrast to
|
||||||
|
* SSLContext#client_ca= no array of X509::Certificate is returned but
|
||||||
|
* X509::Name instances of the CA's subject distinguished name.
|
||||||
|
*
|
||||||
|
* In server mode, returns the list set by SSLContext#client_ca=.
|
||||||
|
* In client mode, returns the list of client CAs sent from the server.
|
||||||
|
*/
|
||||||
|
static VALUE
|
||||||
|
ossl_ssl_get_client_ca_list(VALUE self)
|
||||||
|
{
|
||||||
|
SSL *ssl;
|
||||||
|
STACK_OF(X509_NAME) *ca;
|
||||||
|
|
||||||
|
Data_Get_Struct(self, SSL, ssl);
|
||||||
|
if (!ssl) {
|
||||||
|
rb_warning("SSL session is not started yet.");
|
||||||
|
return Qnil;
|
||||||
|
}
|
||||||
|
|
||||||
|
ca = SSL_get_client_CA_list(ssl);
|
||||||
|
return ossl_x509name_sk2ary(ca);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Init_ossl_ssl()
|
Init_ossl_ssl()
|
||||||
{
|
{
|
||||||
@ -1930,6 +1957,7 @@ Init_ossl_ssl()
|
|||||||
rb_define_method(cSSLSocket, "session_reused?", ossl_ssl_session_reused, 0);
|
rb_define_method(cSSLSocket, "session_reused?", ossl_ssl_session_reused, 0);
|
||||||
rb_define_method(cSSLSocket, "session=", ossl_ssl_set_session, 1);
|
rb_define_method(cSSLSocket, "session=", ossl_ssl_set_session, 1);
|
||||||
rb_define_method(cSSLSocket, "verify_result", ossl_ssl_get_verify_result, 0);
|
rb_define_method(cSSLSocket, "verify_result", ossl_ssl_get_verify_result, 0);
|
||||||
|
rb_define_method(cSSLSocket, "client_ca", ossl_ssl_get_client_ca_list, 0);
|
||||||
|
|
||||||
#define ossl_ssl_def_const(x) rb_define_const(mSSL, #x, INT2NUM(SSL_##x))
|
#define ossl_ssl_def_const(x) rb_define_const(mSSL, #x, INT2NUM(SSL_##x))
|
||||||
|
|
||||||
|
@ -135,6 +135,28 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
|
|||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_client_ca
|
||||||
|
ctx_proc = Proc.new do |ctx|
|
||||||
|
ctx.client_ca = [@ca_cert]
|
||||||
|
end
|
||||||
|
|
||||||
|
vflag = OpenSSL::SSL::VERIFY_PEER|OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT
|
||||||
|
start_server(PORT, vflag, true, :ctx_proc => ctx_proc){|server, port|
|
||||||
|
ctx = OpenSSL::SSL::SSLContext.new
|
||||||
|
client_ca_from_server = nil
|
||||||
|
ctx.client_cert_cb = Proc.new do |sslconn|
|
||||||
|
client_ca_from_server = sslconn.client_ca
|
||||||
|
[@cli_cert, @cli_key]
|
||||||
|
end
|
||||||
|
sock = TCPSocket.new("127.0.0.1", port)
|
||||||
|
ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
|
||||||
|
ssl.sync_close = true
|
||||||
|
ssl.connect
|
||||||
|
assert_equal([@ca], client_ca_from_server)
|
||||||
|
ssl.close
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
def test_starttls
|
def test_starttls
|
||||||
start_server(PORT, OpenSSL::SSL::VERIFY_NONE, false){|server, port|
|
start_server(PORT, OpenSSL::SSL::VERIFY_NONE, false){|server, port|
|
||||||
sock = TCPSocket.new("127.0.0.1", port)
|
sock = TCPSocket.new("127.0.0.1", port)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user