1
0
Fork 0
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:
emboss 2011-06-30 14:48:52 +00:00
parent c4becf8aaf
commit 1dcd4b325e
5 changed files with 108 additions and 41 deletions

View file

@ -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

View file

@ -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)

View file

@ -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{\

View file

@ -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))

View file

@ -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)