mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* 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
5 changed files with 108 additions and 41 deletions
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>
|
||||
|
||||
* 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
|
||||
*/
|
||||
STACK_OF(X509) *
|
||||
ossl_x509_ary2sk0(VALUE ary)
|
||||
{
|
||||
STACK_OF(X509) *sk;
|
||||
VALUE val;
|
||||
X509 *x509;
|
||||
int i;
|
||||
|
||||
Check_Type(ary, T_ARRAY);
|
||||
sk = sk_X509_new_null();
|
||||
if (!sk) ossl_raise(eOSSLError, NULL);
|
||||
|
||||
for (i = 0; i < RARRAY_LEN(ary); i++) {
|
||||
val = rb_ary_entry(ary, i);
|
||||
if (!rb_obj_is_kind_of(val, cX509Cert)) {
|
||||
sk_X509_pop_free(sk, X509_free);
|
||||
ossl_raise(eOSSLError, "object not X509 cert in array");
|
||||
}
|
||||
x509 = DupX509CertPtr(val); /* NEED TO DUP */
|
||||
sk_X509_push(sk, x509);
|
||||
}
|
||||
return sk;
|
||||
}
|
||||
|
||||
STACK_OF(X509) *
|
||||
ossl_protect_x509_ary2sk(VALUE ary, int *status)
|
||||
{
|
||||
return (STACK_OF(X509)*)rb_protect((VALUE(*)_((VALUE)))ossl_x509_ary2sk0,
|
||||
ary, status);
|
||||
}
|
||||
|
||||
STACK_OF(X509) *
|
||||
ossl_x509_ary2sk(VALUE ary)
|
||||
{
|
||||
STACK_OF(X509) *sk;
|
||||
int status = 0;
|
||||
|
||||
sk = ossl_protect_x509_ary2sk(ary, &status);
|
||||
if(status) rb_jump_tag(status);
|
||||
|
||||
return sk;
|
||||
#define OSSL_IMPL_ARY2SK(name, type, expected_class, dup) \
|
||||
STACK_OF(type) * \
|
||||
ossl_##name##_ary2sk0(VALUE ary) \
|
||||
{ \
|
||||
STACK_OF(type) *sk; \
|
||||
VALUE val; \
|
||||
type *x; \
|
||||
int i; \
|
||||
\
|
||||
Check_Type(ary, T_ARRAY); \
|
||||
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); \
|
||||
if (!rb_obj_is_kind_of(val, expected_class)) { \
|
||||
sk_##type##_pop_free(sk, type##_free); \
|
||||
ossl_raise(eOSSLError, "object in array not" \
|
||||
" of class ##type##"); \
|
||||
} \
|
||||
x = dup(val); /* NEED TO DUP */ \
|
||||
sk_##type##_push(sk, x); \
|
||||
} \
|
||||
return sk; \
|
||||
} \
|
||||
\
|
||||
STACK_OF(type) * \
|
||||
ossl_protect_##name##_ary2sk(VALUE ary, int *status) \
|
||||
{ \
|
||||
return (STACK_OF(type)*)rb_protect( \
|
||||
(VALUE(*)_((VALUE)))ossl_##name##_ary2sk0, \
|
||||
ary, \
|
||||
status); \
|
||||
} \
|
||||
\
|
||||
STACK_OF(type) * \
|
||||
ossl_##name##_ary2sk(VALUE ary) \
|
||||
{ \
|
||||
STACK_OF(type) *sk; \
|
||||
int status = 0; \
|
||||
\
|
||||
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) \
|
||||
VALUE \
|
||||
|
@ -117,6 +122,7 @@ ossl_##name##_sk2ary(STACK_OF(type) *sk) \
|
|||
}
|
||||
OSSL_IMPL_SK2ARY(x509, X509)
|
||||
OSSL_IMPL_SK2ARY(x509crl, X509_CRL)
|
||||
OSSL_IMPL_SK2ARY(x509name, X509_NAME)
|
||||
|
||||
static VALUE
|
||||
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*);
|
||||
VALUE ossl_x509_sk2ary(STACK_OF(X509) *certs);
|
||||
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);
|
||||
#define ossl_str_adjust(str, p) \
|
||||
do{\
|
||||
|
|
|
@ -1643,6 +1643,33 @@ ossl_ssl_get_verify_result(VALUE self)
|
|||
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
|
||||
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=", ossl_ssl_set_session, 1);
|
||||
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))
|
||||
|
||||
|
|
|
@ -135,6 +135,28 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
|
|||
}
|
||||
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
|
||||
start_server(PORT, OpenSSL::SSL::VERIFY_NONE, false){|server, port|
|
||||
sock = TCPSocket.new("127.0.0.1", port)
|
||||
|
|
Loading…
Reference in a new issue