[前][次][番号順一覧][スレッド一覧]

ruby-changes:18069

From: drbrain <ko1@a...>
Date: Mon, 6 Dec 2010 09:54:53 +0900 (JST)
Subject: [ruby-changes:18069] Ruby:r30090 (trunk): Add toplevel documentation for OpenSSL

drbrain	2010-12-06 09:54:44 +0900 (Mon, 06 Dec 2010)

  New Revision: 30090

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=30090

  Log:
    Add toplevel documentation for OpenSSL
    
    Add additional documentation for OpenSSL::SSL::SSLContext and
    OpenSSL::SSL::SSLSocket.
    
    Move "let rdoc know about mOSSL" comments so they don't show up in output.

  Modified files:
    trunk/ChangeLog
    trunk/ext/openssl/ossl.c
    trunk/ext/openssl/ossl_asn1.c
    trunk/ext/openssl/ossl_bn.c
    trunk/ext/openssl/ossl_cipher.c
    trunk/ext/openssl/ossl_digest.c
    trunk/ext/openssl/ossl_hmac.c
    trunk/ext/openssl/ossl_pkey.c
    trunk/ext/openssl/ossl_pkey_dh.c
    trunk/ext/openssl/ossl_pkey_dsa.c
    trunk/ext/openssl/ossl_pkey_rsa.c
    trunk/ext/openssl/ossl_rand.c
    trunk/ext/openssl/ossl_ssl.c
    trunk/ext/openssl/ossl_ssl_session.c

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 30089)
+++ ChangeLog	(revision 30090)
@@ -1,3 +1,11 @@
+Mon Dec  6 09:45:11 2010  Eric Hodel  <drbrain@s...>
+
+	* ext/openssl (OpenSSL): add toplevel documentation
+	* ext/openssl/ossl_ssl.c (SSLContext, SSLSocket: add additional
+	  documentation
+	* ext/openssl: move "let rdoc know about mOSSL" comments so they don't
+	  show up in output
+
 Mon Dec  6 09:16:46 2010  NARUSE, Yui  <naruse@r...>
 
 	* lib/uri/common.rb (URI::Parser#initialize_pattern):
Index: ext/openssl/ossl_pkey_dsa.c
===================================================================
--- ext/openssl/ossl_pkey_dsa.c	(revision 30089)
+++ ext/openssl/ossl_pkey_dsa.c	(revision 30090)
@@ -445,8 +445,8 @@
 void
 Init_ossl_dsa()
 {
-#if 0 /* let rdoc know about mOSSL and mPKey */
-    mOSSL = rb_define_module("OpenSSL");
+#if 0
+    mOSSL = rb_define_module("OpenSSL"); /* let rdoc know about mOSSL and mPKey */
     mPKey = rb_define_module_under(mOSSL, "PKey");
 #endif
 
Index: ext/openssl/ossl_ssl.c
===================================================================
--- ext/openssl/ossl_ssl.c	(revision 30089)
+++ ext/openssl/ossl_ssl.c	(revision 30090)
@@ -152,7 +152,7 @@
  *    ctx.ssl_version = :TLSv1
  *    ctx.ssl_version = "SSLv23_client"
  *
- * You can get a list of valid methods with OpenSSL::SSL::SSLContext::METHODS
+ * You can get a list of valid versions with OpenSSL::SSL::SSLContext::METHODS
  */
 static VALUE
 ossl_sslctx_set_ssl_version(VALUE self, VALUE ssl_method)
@@ -527,7 +527,8 @@
  *    ctx.setup => nil # thereafter
  *
  * This method is called automatically when a new SSLSocket is created.
- * Normally you do not need to call this method (unless you are writing an extension in C).
+ * Normally you do not need to call this method (unless you are writing an
+ * extension in C).
  */
 static VALUE
 ossl_sslctx_setup(VALUE self)
@@ -687,6 +688,8 @@
 /*
  * call-seq:
  *    ctx.ciphers => [[name, version, bits, alg_bits], ...]
+ *
+ * The list of ciphers configured for this context.
  */
 static VALUE
 ossl_sslctx_get_ciphers(VALUE self)
@@ -769,6 +772,7 @@
  *  call-seq:
  *     ctx.session_add(session) -> true | false
  *
+ * Adds +session+ to the session cache
  */
 static VALUE
 ossl_sslctx_session_add(VALUE self, VALUE arg)
@@ -786,6 +790,7 @@
  *  call-seq:
  *     ctx.session_remove(session) -> true | false
  *
+ * Removes +session+ from the session cache
  */
 static VALUE
 ossl_sslctx_session_remove(VALUE self, VALUE arg)
@@ -801,8 +806,9 @@
 
 /*
  *  call-seq:
- *     ctx.session_cache_mode -> integer
+ *     ctx.session_cache_mode -> Integer
  *
+ * The current session cache mode.
  */
 static VALUE
 ossl_sslctx_get_session_cache_mode(VALUE self)
@@ -816,8 +822,11 @@
 
 /*
  *  call-seq:
- *     ctx.session_cache_mode=(integer) -> integer
+ *     ctx.session_cache_mode=(integer) -> Integer
  *
+ * Sets the SSL session cache mode.  Bitwise-or together the desired
+ * SESSION_CACHE_* constants to set.  See SSL_CTX_set_session_cache_mode(3) for
+ * details.
  */
 static VALUE
 ossl_sslctx_set_session_cache_mode(VALUE self, VALUE arg)
@@ -833,8 +842,10 @@
 
 /*
  *  call-seq:
- *     ctx.session_cache_size -> integer
+ *     ctx.session_cache_size -> Integer
  *
+ * Returns the current session cache size.  Zero is used to represent an
+ * unlimited cache size.
  */
 static VALUE
 ossl_sslctx_get_session_cache_size(VALUE self)
@@ -848,8 +859,10 @@
 
 /*
  *  call-seq:
- *     ctx.session_cache_size=(integer) -> integer
+ *     ctx.session_cache_size=(integer) -> Integer
  *
+ * Sets the session cache size.  Returns the previously valid session cache
+ * size.  Zero is used to represent an unlimited session cache size.
  */
 static VALUE
 ossl_sslctx_set_session_cache_size(VALUE self, VALUE arg)
@@ -867,6 +880,23 @@
  *  call-seq:
  *     ctx.session_cache_stats -> Hash
  *
+ * Returns a Hash containing the following keys:
+ *
+ * :accept:: Number of started SSL/TLS handshakes in server mode
+ * :accept_good:: Number of established SSL/TLS sessions in server mode
+ * :accept_renegotiate:: Number of start renegotiations in server mode
+ * :cache_full:: Number of sessions that were removed due to cache overflow
+ * :cache_hits:: Number of successfully reused connections
+ * :cache_misses:: Number of sessions proposed by clients that were not found
+ *                 in the cache
+ * :cache_num:: Number of sessions in the internal session cache
+ * :cb_hits:: Number of sessions retrieved from the external cache in server
+ *            mode
+ * :connect:: Number of started SSL/TLS handshakes in client mode
+ * :connect_good:: Number of established SSL/TLS sessions in client mode
+ * :connect_renegotiate:: Number of start renegotiations in client mode
+ * :timeouts:: Number of sessions proposed by clients that were found in the
+ *             cache but had expired due to timeouts
  */
 static VALUE
 ossl_sslctx_get_session_cache_stats(VALUE self)
@@ -898,6 +928,7 @@
  *  call-seq:
  *     ctx.flush_sessions(time | nil) -> self
  *
+ * Removes sessions in the internal cache that have expired at +time+.
  */
 static VALUE
 ossl_sslctx_flush_sessions(int argc, VALUE *argv, VALUE self)
@@ -953,10 +984,12 @@
  *    SSLSocket.new(io) => aSSLSocket
  *    SSLSocket.new(io, ctx) => aSSLSocket
  *
- * === Parameters
- * * +io+ is a real ruby IO object.  Not an IO like object that responds to read/write.
- * * +ctx+ is an OpenSSLSSL::SSLContext.
+ * Creates a new SSL socket from +io+ which must be a real ruby object (not an
+ * IO-like object that responds to read/write.
  *
+ * If +ctx+ is provided the SSL Sockets initial params will be taken from
+ * the context.
+ *
  * The OpenSSL::Buffering module provides additional IO methods.
  *
  * This method will freeze the SSLContext if one is provided;
@@ -1101,6 +1134,9 @@
 /*
  * call-seq:
  *    ssl.connect => self
+ *
+ * Initiates an SSL/TLS handshake with a server.  The handshake may be started
+ * after unencrypted data has been sent over the socket.
  */
 static VALUE
 ossl_ssl_connect(VALUE self)
@@ -1113,7 +1149,7 @@
  * call-seq:
  *    ssl.connect_nonblock => self
  *
- * initiate the TLS/SSL handshake as a client in non-blocking manner.
+ * Initiates the SSL/TLS handshake as a client in non-blocking manner.
  *
  *   # emulates blocking connect
  *   begin
@@ -1137,6 +1173,9 @@
 /*
  * call-seq:
  *    ssl.accept => self
+ *
+ * Waits for a SSL/TLS client to initiate a handshake.  The handshake may be
+ * started after unencrypted data has been sent over the socket.
  */
 static VALUE
 ossl_ssl_accept(VALUE self)
@@ -1149,7 +1188,7 @@
  * call-seq:
  *    ssl.accept_nonblock => self
  *
- * initiate the TLS/SSL handshake as a server in non-blocking manner.
+ * Initiates the SSL/TLS handshake as a server in non-blocking manner.
  *
  *   # emulates blocking accept
  *   begin
@@ -1235,9 +1274,8 @@
  *    ssl.sysread(length) => string
  *    ssl.sysread(length, buffer) => buffer
  *
- * === Parameters
- * * +length+ is a positive integer.
- * * +buffer+ is a string used to store the result.
+ * Reads +length+ bytes from the SSL connection.  If a pre-allocated +buffer+
+ * is provided the data will be written into it.
  */
 static VALUE
 ossl_ssl_read(int argc, VALUE *argv, VALUE self)
@@ -1250,9 +1288,11 @@
  *    ssl.sysread_nonblock(length) => string
  *    ssl.sysread_nonblock(length, buffer) => buffer
  *
- * === Parameters
- * * +length+ is a positive integer.
- * * +buffer+ is a string used to store the result.
+ * A non-blocking version of #sysread.  Raises an SSLError if reading would
+ * block.
+ *
+ * Reads +length+ bytes from the SSL connection.  If a pre-allocated +buffer+
+ * is provided the data will be written into it.
  */
 static VALUE
 ossl_ssl_read_nonblock(int argc, VALUE *argv, VALUE self)
@@ -1304,7 +1344,9 @@
 
 /*
  * call-seq:
- *    ssl.syswrite(string) => integer
+ *    ssl.syswrite(string) => Integer
+ *
+ * Writes +string+ to the SSL connection.
  */
 static VALUE
 ossl_ssl_write(VALUE self, VALUE str)
@@ -1314,7 +1356,10 @@
 
 /*
  * call-seq:
- *    ssl.syswrite_nonblock(string) => integer
+ *    ssl.syswrite_nonblock(string) => Integer
+ *
+ * Writes +string+ to the SSL connection in a non-blocking manner.  Raises an
+ * SSLError if writing would block.
  */
 static VALUE
 ossl_ssl_write_nonblock(VALUE self, VALUE str)
@@ -1325,6 +1370,8 @@
 /*
  * call-seq:
  *    ssl.sysclose => nil
+ *
+ * Shuts down the SSL connection and prepares it for another connection.
  */
 static VALUE
 ossl_ssl_close(VALUE self)
@@ -1342,6 +1389,8 @@
 /*
  * call-seq:
  *    ssl.cert => cert or nil
+ *
+ * The X509 certificate for this socket endpoint.
  */
 static VALUE
 ossl_ssl_get_cert(VALUE self)
@@ -1370,6 +1419,8 @@
 /*
  * call-seq:
  *    ssl.peer_cert => cert or nil
+ *
+ * The X509 certificate for this socket's peer.
  */
 static VALUE
 ossl_ssl_get_peer_cert(VALUE self)
@@ -1399,6 +1450,8 @@
 /*
  * call-seq:
  *    ssl.peer_cert_chain => [cert, ...] or nil
+ *
+ * The X509 certificate chain for this socket's peer.
  */
 static VALUE
 ossl_ssl_get_peer_cert_chain(VALUE self)
@@ -1429,6 +1482,8 @@
 /*
  * call-seq:
  *    ssl.cipher => [name, version, bits, alg_bits]
+ *
+ * The cipher being used for the current connection
  */
 static VALUE
 ossl_ssl_get_cipher(VALUE self)
@@ -1449,6 +1504,8 @@
 /*
  * call-seq:
  *    ssl.state => string
+ *
+ * A description of the current connection state.
  */
 static VALUE
 ossl_ssl_get_state(VALUE self)
@@ -1471,7 +1528,9 @@
 
 /*
  * call-seq:
- *    ssl.pending => integer
+ *    ssl.pending => Integer
+ *
+ * The number of bytes that are immediately available for reading
  */
 static VALUE
 ossl_ssl_pending(VALUE self)
@@ -1488,9 +1547,10 @@
 }
 
 /*
- *  call-seq:
- *     ssl.session_reused? -> true | false
+ * call-seq:
+ *    ssl.session_reused? -> true | false
  *
+ * Returns true if a reused session was negotiated during the handshake.
  */
 static VALUE
 ossl_ssl_session_reused(VALUE self)
@@ -1511,9 +1571,10 @@
 }
 
 /*
- *  call-seq:
- *     ssl.session = session -> session
+ * call-seq:
+ *    ssl.session = session -> session
  *
+ * Sets the Session to be used when the connection is established.
  */
 static VALUE
 ossl_ssl_set_session(VALUE self, VALUE arg1)
@@ -1538,6 +1599,15 @@
     return arg1;
 }
 
+/*
+ * call-seq:
+ *    ssl.verify_result => Integer
+ *
+ * Returns the result of the peer certificates verification.  See verify(1)
+ * for error values and descriptions.
+ *
+ * If no peer certificate was presented X509_V_OK is returned.
+ */
 static VALUE
 ossl_ssl_get_verify_result(VALUE self)
 {
@@ -1558,8 +1628,8 @@
     int i;
     VALUE ary;
 
-#if 0 /* let rdoc know about mOSSL */
-    mOSSL = rb_define_module("OpenSSL");
+#if 0
+    mOSSL = rb_define_module("OpenSSL"); /* let rdoc know about mOSSL */
 #endif
 
     ID_callback_state = rb_intern("@callback_state");
@@ -1577,18 +1647,161 @@
 
     Init_ossl_ssl_session();
 
-    /* class SSLContext
+    /* Document-class: OpenSSL::SSL::SSLContext
      *
-     * The following attributes are available but don't show up in rdoc.
-     * All attributes must be set before calling SSLSocket.new(io, ctx).
+     * An SSLContext is used to set various options regarding certificates,
+     * algorithms, verification, session caching, etc.  The SSLContext is
+     * used to create an SSLSocket.
+     *
+     * All attributes must be set before creating an SSLSocket as the
+     * SSLContext will be frozen afterward.
+     *
+     * The following attributes are available but don't show up in rdoc:
      * * ssl_version, cert, key, client_ca, ca_file, ca_path, timeout,
      * * verify_mode, verify_depth client_cert_cb, tmp_dh_callback,
      * * session_id_context, session_add_cb, session_new_cb, session_remove_cb
      */
     cSSLContext = rb_define_class_under(mSSL, "SSLContext", rb_cObject);
     rb_define_alloc_func(cSSLContext, ossl_sslctx_s_alloc);
-    for(i = 0; i < numberof(ossl_sslctx_attrs); i++)
-        rb_attr(cSSLContext, rb_intern(ossl_sslctx_attrs[i]), 1, 1, Qfalse);
+
+    /*
+     * Context certificate
+     */
+    rb_attr(cSSLContext, rb_intern("cert"), 1, 1, Qfalse);
+
+    /*
+     * Context private key
+     */
+    rb_attr(cSSLContext, rb_intern("key"), 1, 1, Qfalse);
+
+    /*
+     * A certificate or Array of certificates that will be sent to the client.
+     */
+    rb_attr(cSSLContext, rb_intern("client_ca"), 1, 1, Qfalse);
+
+    /*
+     * The path to a file containing a PEM-format CA certificate
+     */
+    rb_attr(cSSLContext, rb_intern("ca_file"), 1, 1, Qfalse);
+
+    /*
+     * The path to a directory containing CA certificates in PEM format.
+     *
+     * Files are looked up by subject's X509 name's hash value.
+     */
+    rb_attr(cSSLContext, rb_intern("ca_path"), 1, 1, Qfalse);
+
+    /*
+     * Maximum session lifetime.
+     */
+    rb_attr(cSSLContext, rb_intern("timeout"), 1, 1, Qfalse);
+
+    /*
+     * Session verification mode.
+     *
+     * Valid modes are VERIFY_NONE, VERIFY_PEER, VERIFY_CLIENT_ONCE,
+     * VERIFY_FAIL_IF_NO_PEER_CERT and defined on OpenSSL::SSL
+     */
+    rb_attr(cSSLContext, rb_intern("verify_mode"), 1, 1, Qfalse);
+
+    /*
+     * Number of CA certificates to walk when verifying a certificate chain.
+     */
+    rb_attr(cSSLContext, rb_intern("verify_depth"), 1, 1, Qfalse);
+
+    /*
+     * A callback for additional certificate verification.  The callback is
+     * invoked for each certificate in the chain.
+     *
+     * The callback is invoked with two values.  +preverify_ok+ indicates
+     * indicates if the verification was passed (true) or not (false).
+     * +store_context+ is an OpenSSL::X509::StoreContext containing the
+     * context used for certificate verification.
+     *
+     * If the callback returns false verification is stopped.
+     */
+    rb_attr(cSSLContext, rb_intern("verify_callback"), 1, 1, Qfalse);
+
+    /*
+     * Sets various OpenSSL options.
+     */
+    rb_attr(cSSLContext, rb_intern("options"), 1, 1, Qfalse);
+
+    /*
+     * An OpenSSL::X509::Store used for certificate verification
+     */
+    rb_attr(cSSLContext, rb_intern("cert_store"), 1, 1, Qfalse);
+
+    /*
+     * An Array of extra X509 certificates to be added to the certificate
+     * chain.
+     */
+    rb_attr(cSSLContext, rb_intern("extra_chain_cert"), 1, 1, Qfalse);
+
+    /*
+     * A callback invoked when a client certificate is requested by a server
+     * and no certificate has been set.
+     *
+     * The callback is invoked with a Session and must return an Array
+     * containing an OpenSSL::X509::Certificate and an OpenSSL::PKey.  If any
+     * other value is returned the handshake is suspended.
+     */
+    rb_attr(cSSLContext, rb_intern("client_cert_cb"), 1, 1, Qfalse);
+
+    /*
+     * A callback invoked when DH parameters are required.
+     *
+     * The callback is invoked with the Session for the key exchange, an
+     * flag indicating the use of an export cipher and the keylength
+     * required.
+     *
+     * The callback must return an OpenSSL::PKey::DH instance of the correct
+     * key length.
+     */
+    rb_attr(cSSLContext, rb_intern("tmp_dh_callback"), 1, 1, Qfalse);
+
+    /*
+     * Sets the context in which a session can be reused.  This allows
+     * sessions for multiple applications to be distinguished, for exapmle, by
+     * name.
+     */
+    rb_attr(cSSLContext, rb_intern("session_id_context"), 1, 1, Qfalse);
+
+    /*
+     * A callback invoked on a server when a session is proposed by the client
+     * but the session could not be found in the server's internal cache.
+     *
+     * The callback is invoked with the SSLSocket and session id.  The
+     * callback may return a Session from an external cache.
+     */
+    rb_attr(cSSLContext, rb_intern("session_get_cb"), 1, 1, Qfalse);
+
+    /*
+     * A callback invoked when a new session was negotiatied.
+     *
+     * The callback is invoked with an SSLSocket.  If false is returned the
+     * session will be removed from the internal cache.
+     */
+    rb_attr(cSSLContext, rb_intern("session_new_cb"), 1, 1, Qfalse);
+
+    /*
+     * A callback invoked when a session is removed from the internal cache.
+     *
+     * The callback is invoked with an SSLContext and a Session.
+     */
+    rb_attr(cSSLContext, rb_intern("session_remove_cb"), 1, 1, Qfalse);
+
+#ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME
+    /*
+     * A callback invoked at connect time to distinguish between multiple
+     * server names.
+     *
+     * The callback is invoked with an SSLSocket and a server name.  The
+     * callback must return an SSLContext for the server name or nil.
+     */
+    rb_attr(cSSLContext, rb_intern("servername_cb"), 1, 1, Qfalse);
+#endif
+
     rb_define_alias(cSSLContext, "ssl_timeout", "timeout");
     rb_define_alias(cSSLContext, "ssl_timeout=", "timeout=");
     rb_define_method(cSSLContext, "initialize",  ossl_sslctx_initialize, -1);
@@ -1599,14 +1812,53 @@
     rb_define_method(cSSLContext, "setup", ossl_sslctx_setup, 0);
 
 
+    /*
+     * No session caching for client or server
+     */
     rb_define_const(cSSLContext, "SESSION_CACHE_OFF", LONG2FIX(SSL_SESS_CACHE_OFF));
+
+    /*
+     * Client sessions are added to the session cache
+     */
     rb_define_const(cSSLContext, "SESSION_CACHE_CLIENT", LONG2FIX(SSL_SESS_CACHE_CLIENT)); /* doesn't actually do anything in 0.9.8e */
+
+    /*
+     * Server sessions are added to the session cache
+     */
     rb_define_const(cSSLContext, "SESSION_CACHE_SERVER", LONG2FIX(SSL_SESS_CACHE_SERVER));
+
+    /*
+     * Both client and server sessions are added to the session cache
+     */
     rb_define_const(cSSLContext, "SESSION_CACHE_BOTH", LONG2FIX(SSL_SESS_CACHE_BOTH)); /* no different than CACHE_SERVER in 0.9.8e */
+
+    /*
+     * Normally the sesison cache is checked for expired sessions every 255
+     * connections.  Since this may lead to a delay that cannot be controlled,
+     * the automatic flushing may be disabled and #flush_sessions can be
+     * called explicitly.
+     */
     rb_define_const(cSSLContext, "SESSION_CACHE_NO_AUTO_CLEAR", LONG2FIX(SSL_SESS_CACHE_NO_AUTO_CLEAR));
+
+    /*
+     * Always perform external lookups of sessions even if they are in the
+     * internal cache.
+     *
+     * This flag has no effect on clients
+     */
     rb_define_const(cSSLContext, "SESSION_CACHE_NO_INTERNAL_LOOKUP", LONG2FIX(SSL_SESS_CACHE_NO_INTERNAL_LOOKUP));
+
+    /*
+     * Never automatically store sessions in the internal store.
+     */
     rb_define_const(cSSLContext, "SESSION_CACHE_NO_INTERNAL_STORE", LONG2FIX(SSL_SESS_CACHE_NO_INTERNAL_STORE));
+
+    /*
+     * Enables both SESSION_CACHE_NO_INTERNAL_LOOKUP and
+     * SESSION_CACHE_NO_INTERNAL_STORE.
+     */
     rb_define_const(cSSLContext, "SESSION_CACHE_NO_INTERNAL", LONG2FIX(SSL_SESS_CACHE_NO_INTERNAL));
+
     rb_define_method(cSSLContext, "session_add",     ossl_sslctx_session_add, 1);
     rb_define_method(cSSLContext, "session_remove",     ossl_sslctx_session_remove, 1);
     rb_define_method(cSSLContext, "session_cache_mode",     ossl_sslctx_get_session_cache_mode, 0);
@@ -1621,10 +1873,11 @@
         rb_ary_push(ary, ID2SYM(rb_intern(ossl_ssl_method_tab[i].name)));
     }
     rb_obj_freeze(ary);
-    /* holds a list of available SSL/TLS methods */
+    /* The list of available SSL/TLS methods */
     rb_define_const(cSSLContext, "METHODS", ary);
 
-    /* class SSLSocket
+    /*
+     * Document-class: OpenSSL::SSL::SSLSocket
      *
      * The following attributes are available but don't show up in rdoc.
      * * io, context, sync_close
Index: ext/openssl/ossl_hmac.c
===================================================================
--- ext/openssl/ossl_hmac.c	(revision 30089)
+++ ext/openssl/ossl_hmac.c	(revision 30090)
@@ -236,8 +236,8 @@
 void
 Init_ossl_hmac()
 {
-#if 0 /* let rdoc know about mOSSL */
-    mOSSL = rb_define_module("OpenSSL");
+#if 0
+    mOSSL = rb_define_module("OpenSSL"); /* let rdoc know about mOSSL */
 #endif
 
     eHMACError = rb_define_class_under(mOSSL, "HMACError", eOSSLError);
Index: ext/openssl/ossl_cipher.c
===================================================================
--- ext/openssl/ossl_cipher.c	(revision 30089)
+++ ext/openssl/ossl_cipher.c	(revision 30090)
@@ -518,8 +518,8 @@
 void
 Init_ossl_cipher(void)
 {
-#if 0 /* let rdoc know about mOSSL */
-    mOSSL = rb_define_module("OpenSSL");
+#if 0
+    mOSSL = rb_define_module("OpenSSL"); /* let rdoc know about mOSSL */
 #endif
     cCipher = rb_define_class_under(mOSSL, "Cipher", rb_cObject);
     eCipherError = rb_define_class_under(cCipher, "CipherError", eOSSLError);
Index: ext/openssl/ossl_pkey_rsa.c
===================================================================
--- ext/openssl/ossl_pkey_rsa.c	(revision 30089)
+++ ext/openssl/ossl_pkey_rsa.c	(revision 30090)
@@ -536,8 +536,8 @@
 void
 Init_ossl_rsa()
 {
-#if 0 /* let rdoc know about mOSSL and mPKey */
-    mOSSL = rb_define_module("OpenSSL");
+#if 0
+    mOSSL = rb_define_module("OpenSSL"); /* let rdoc know about mOSSL and mPKey */
     mPKey = rb_define_module_under(mOSSL, "PKey");
 #endif
 
Index: ext/openssl/ossl_digest.c
===================================================================
--- ext/openssl/ossl_digest.c	(revision 30089)
+++ ext/openssl/ossl_digest.c	(revision 30090)
@@ -235,8 +235,8 @@
 {
     rb_require("digest");
 
-#if 0 /* let rdoc know about mOSSL */
-    mOSSL = rb_define_module("OpenSSL");
+#if 0
+    mOSSL = rb_define_module("OpenSSL"); /* let rdoc know about mOSSL */
 #endif
 
     cDigest = rb_define_class_under(mOSSL, "Digest", rb_path2class("Digest::Class"));
Index: ext/openssl/ossl.c
===================================================================
--- ext/openssl/ossl.c	(revision 30089)
+++ ext/openssl/ossl.c	(revision 30090)
@@ -407,7 +407,313 @@
 }
 
 /*
- * OSSL library init
+ * OpenSSL provides SSL, TLS and general purpose cryptography.  It wraps the
+ * OpenSSL[http://www.openssl.org/] library.
+ *
+ * = Examples
+ *
+ * All examples assume you have loaded OpenSSL with:
+ *
+ *   require 'openssl'
+ *
+ * These examples build atop each other.  For example the key created in the
+ * next is used in throughout these examples.
+ *
+ * == Keys
+ *
+ * === Creating a Key
+ *
+ * This example creates a 2048 bit RSA keypair and writes it to the current
+ * directory.
+ *
+ *   key = OpenSSL::PKey::RSA.new 2048
+ *
+ *   open 'private_key.pem', 'w' do |io| io.write key.to_pem end
+ *   open 'public_key.pem', 'w' do |io| io.write key.public_key.to_pem end
+ *
+ * === Exporting a Key
+ *
+ * Keys saved to disk without encryption are not secure as anyone who gets
+ * ahold of the key may use it unless it is encrypted.  In order to securely
+ * export a key you may export it with a pass phrase.
+ *
+ *   cipher = OpenSSL::Cipher::Cipher.new 'AES-128-CBC'
+ *   pass_phrase = 'my secure pass phrase goes here'
+ *
+ *   key_secure = key.export cipher, pass_phrase
+ *
+ *   open 'private.secure.pem', 'w' do |io|
+ *     io.write key_secure
+ *   end
+ *
+ * OpenSSL::Cipher.ciphers returns a list of available ciphers.
+ *
+ * === Loading a Key
+ *
+ * A key can also be loaded from a file.
+ *
+ *   key2 = OpenSSL::PKey::RSA.new File.read 'private_key.pem'
+ *   key2.public? # => true
+ *
+ * or
+ *
+ *   key3 = OpenSSL::PKey::RSA.new File.read 'public_key.pem'
+ *   key3.private? # => false
+ *
+ * === Loading an Encrypted Key
+ *
+ * OpenSSL will prompt you for your pass phrase when loading an encrypted key.
+ * If you will not be able to type in the pass phrase you may provide it when
+ * loading the key:
+ *
+ *   key4_pem = File.read 'private.secure.pem'
+ *   key4 = OpenSSL::PKey::RSA.new key4_pem, pass_phrase
+ *
+ * == X509 Certificates
+ *
+ * === Creating a Certificate
+ *
+ * This example creates a self-signed certificate using an RSA key and a SHA1
+ * signature.
+ *
+ *   name = OpenSSL::X509::Name.parse 'CN=nobody/DC=example'
+ *
+ *   cert = OpenSSL::X509::Certificate.new
+ *   cert.version = 2
+ *   cert.serial = 0
+ *   cert.not_before = Time.now
+ *   cert.not_after = Time.now + 3600
+ *
+ *   cert.public_key = key.public_key
+ *   cert.subject = name
+ *
+ * === Certificate Extensions
+ *
+ * You can add extensions to the certificate with
+ * OpenSSL::SSL::ExtensionFactory to indicate the purpose of the certificate.
+ *
+ *   extension_factory = OpenSSL::X509::ExtensionFactory.new nil, cert
+ *
+ *   extension_factory.create_extension 'basicConstraints', 'CA:FALSE'
+ *   extension_factory.create_extension 'keyUsage',
+ *     'keyEncipherment,dataEncipherment,digitalSignature'
+ *   extension_factory.create_extension 'subjectKeyIdentifier', 'hash'
+ *
+ * === Signing a Certificate
+ *
+ * To sign a certificate set the issuer and use OpenSSL::X509::Certificate#sign
+ * with a digest algorithm.  This creates a self-signed cert because we're using
+ * the same name and key to sign the certificate as was used to create the
+ * certificate.
+ *
+ *   cert.issuer = name
+ *   cert.sign key, OpenSSL::Digest::SHA1.new
+ *
+ *   open 'certificate.pem', 'w' do |io| io.write cert.to_pem end
+ *
+ * === Loading a Certificate
+ *
+ * Like a key, a cert can also be loaded from a file.
+ *
+ *   cert2 = OpenSSL::X509::Certificate.new File.read 'certificate.pem'
+ *
+ * === Verifying a Certificate
+ *
+ * Certificate#verify will return true when a certificate was signed with the
+ * given public key.
+ *
+ *   raise 'certificate can not be verified' unless cert2.verify key
+ *
+ * == Certificate Authority
+ *
+ * A certificate authority (CA) is a trusted third party that allows you to
+ * verify the ownership of unknown certificates.  The CA issues key signatures
+ * that indicate it trusts the user of that key.  A user encountering the key
+ * can verify the signature by using the CA's public key.
+ *
+ * === CA Key
+ *
+ * CA keys are valuable, so we encrypt and save it to disk and make sure it is
+ * not readable by other users.
+ *
+ *   ca_key = OpenSSL::PKey::RSA.new 2048
+ *
+ *   cipher = OpenSSL::Cipher::AES.new 128, :CBC
+ *
+ *   open 'ca_key.pem', 'w', 0400 do |io|
+ *     io.write key.export(cipher, pass_phrase)
+ *   end
+ *
+ * === CA Certificate
+ *
+ * A CA certificate is created the same way we created a certificate above, but
+ * with different extensions.
+ *
+ *   ca_name = OpenSSL::X509::Name.parse 'CN=ca/DC=example'
+ *
+ *   ca_cert = OpenSSL::X509::Certificate.new
+ *   ca_cert.serial = 0
+ *   ca_cert.version = 2
+ *   ca_cert.not_before = Time.now
+ *   ca_cert.not_after = Time.now + 86400
+ *
+ *   ca_cert.public_key = ca_key.public_key
+ *   ca_cert.subject = ca_name
+ *   ca_cert.issuer = ca_name
+ *
+ *   extension_factory = OpenSSL::X509::ExtensionFactory.new
+ *   extension_factory.subject_certificate = ca_cert
+ *   extension_factory.issuer_certificate = ca_cert
+ *
+ *   extension_factory.create_extension 'subjectKeyIdentifier', 'hash'
+ *
+ * This extension indicates the CA's key may be used as a CA.
+ *
+ *   extension_factory.create_extension 'basicConstraints', 'CA:TRUE', true
+ *
+ * This extension indicates the CA's key may be used to verify signatures on
+ * both certificates and certificate revocations.
+ *
+ *   extension_factory.create_extension 'keyUsage', 'cRLSign,keyCertSign', true
+ *
+ * Root CA certificates are self-signed.
+ *
+ *   ca_cert.sign ca_key, OpenSSL::Digest::SHA1.new
+ *
+ * The CA certificate is saved to disk so it may be distributed to all the
+ * users of the keys this CA will sign.
+ *
+ *   open 'ca_cert.pem', 'w' do |io|
+ *     io.write ca_cert.to_pem
+ *   end
+ *
+ * === Certificate Signing Request
+ *
+ * The CA signs keys through a Certificate Signing Request (CSR).  The CSR
+ * contains the information necessary to identify the key.
+ *
+ *   csr = OpenSSL::X509::Request.new
+ *   csr.version = 0
+ *   csr.subject = name
+ *   csr.public_key = key.public_key
+ *   csr.sign key, OpenSSL::Digest::SHA1.new
+ *
+ * A CSR is saved to disk and sent to the CA for signing.
+ *
+ *   open 'csr.pem', 'w' do |io|
+ *     io.write csr.to_pem
+ *   end
+ *
+ * === Creating a Certificate from a CSR
+ *
+ * Upon receiving a CSR the CA will verify it before signing it.  A minimal
+ * verification would be to check the CSR's signature.
+ *
+ *   csr = OpenSSL::X509::Request.new File.read 'csr.pem'
+ *
+ *   raise 'CSR can not be verified' unless csr.verify csr.public_key
+ *
+ * After verification a certificate is created, marked for various usages,
+ * signed with the CA key and returned to the requester.
+ *
+ *   csr_cert = OpenSSL::X509::Certificate.new
+ *   csr_cert.serial = 0
+ *   csr_cert.version = 2
+ *   csr_cert.not_before = Time.now
+ *   csr_cert.not_after = Time.now + 600
+ *
+ *   csr_cert.subject = csr.subject
+ *   csr_cert.public_key = csr.public_key
+ *   csr_cert.issuer = ca_cert.subject
+ *
+ *   extension_factory = OpenSSL::X509::ExtensionFactory.new
+ *   extension_factory.subject_certificate = csr_cert
+ *   extension_factory.issuer_certificate = ca_cert
+ *
+ *   extension_factory.create_extension 'basicConstraints', 'CA:FALSE'
+ *   extension_factory.create_extension 'keyUsage',
+ *     'keyEncipherment,dataEncipherment,digitalSignature'
+ *   extension_factory.create_extension 'subjectKeyIdentifier', 'hash'
+ *
+ *   csr_cert.sign ca_key, OpenSSL::Digest::SHA1.new
+ *
+ *   open 'csr_cert.pem', 'w' do |io|
+ *     io.write csr_cert.to_pem
+ *   end
+ *
+ * == SSL and TLS Connections
+ *
+ * Using our created key and certificate we can create an SSL or TLS connection.
+ * An SSLContext is used to set up an SSL session.
+ *
+ *   context = OpenSSL::SSL::SSLContext.new
+ *
+ * === SSL Server
+ *
+ * An SSL server requires the certificate and private key to communicate
+ * securely with its clients:
+ *
+ *   context.cert = cert
+ *   context.key = key
+ *
+ * Then create an SSLServer with a TCP server socket and the context.  Use the
+ * SSLServer like an ordinary TCP server.
+ *
+ *   require 'socket'
+ *
+ *   tcp_server = TCPServer.new 5000
+ *   ssl_server = OpenSSL::SSL::SSLServer.new tcp_server, context
+ *
+ *   loop do
+ *     ssl_connection = ssl_server.accept
+ *
+ *     data = connection.gets
+ *
+ *     response = "I got #{data.dump}"
+ *     puts response
+ *
+ *     connection.puts "I got #{data.dump}"
+ *     connection.close
+ *   end
+ *
+ * === SSL client
+ *
+ * An SSL client is created with a TCP socket and the context.
+ * SSLSocket#connect must be called to initiate the SSL handshake and start
+ * encryption.  A key and certificate are not required for the client socket.
+ *
+ *   require 'socket'
+ *
+ *   tcp_client = TCPSocket.new 'localhost', 5000
+ *   ssl_client = OpenSSL::SSL::SSLSocket.new client_socket, context
+ *   ssl_client.connect
+ *
+ *   ssl_client.puts "hello server!"
+ *   puts ssl_client.gets
+ *
+ * === Peer Verification
+ *
+ * An unverified SSL connection does not provide much security.  For enhanced
+ * security the client or server can verify the certificate the of its peer.
+ *
+ * The client can be modified to verify the server's certificate against the
+ * certificate authority's certificate:
+ *
+ *   context.ca_file = 'ca_cert.pem'
+ *   context.verify_mode = OpenSSL::SSL::VERIFY_PEER
+ *
+ *   require 'socket'
+ *
+ *   tcp_client = TCPSocket.new 'localhost', 5000
+ *   ssl_client = OpenSSL::SSL::SSLSocket.new client_socket, context
+ *   ssl_client.connect
+ *
+ *   ssl_client.puts "hello server!"
+ *   puts ssl_client.gets
+ *
+ * If the server certificate is invalid or <tt>context.ca_file</tt> is not set
+ * when verifying peers an OpenSSL::SSL::SSLError will be raised.
+ *
  */
 void
 Init_openssl()
Index: ext/openssl/ossl_bn.c
===================================================================
--- ext/openssl/ossl_bn.c	(revision 30089)
+++ ext/openssl/ossl_bn.c	(revision 30090)
@@ -731,8 +731,8 @@
 void
 Init_ossl_bn()
 {
-#if 0 /* let rdoc know about mOSSL */
-    mOSSL = rb_define_module("OpenSSL");
+#if 0
+    mOSSL = rb_define_module("OpenSSL"); /* let rdoc know about mOSSL */
 #endif
 
     if (!(ossl_bn_ctx = BN_CTX_new())) {
Index: ext/openssl/ossl_asn1.c
===================================================================
--- ext/openssl/ossl_asn1.c	(revision 30089)
+++ ext/openssl/ossl_asn1.c	(revision 30090)
@@ -1087,8 +1087,8 @@
     VALUE ary;
     int i;
 
-#if 0 /* let rdoc know about mOSSL */
-    mOSSL = rb_define_module("OpenSSL");
+#if 0
+    mOSSL = rb_define_module("OpenSSL"); /* let rdoc know about mOSSL */
 #endif
 
     sUNIVERSAL = rb_intern("UNIVERSAL");
Index: ext/openssl/ossl_ssl_session.c
===================================================================
--- ext/openssl/ossl_ssl_session.c	(revision 30089)
+++ ext/openssl/ossl_ssl_session.c	(revision 30090)
@@ -278,8 +278,8 @@
 
 void Init_ossl_ssl_session(void)
 {
-#if 0 /* let rdoc know about mOSSL */
-	mOSSL = rb_define_module("OpenSSL");
+#if 0
+	mOSSL = rb_define_module("OpenSSL"); /* let rdoc know about mOSSL */
 	mSSL = rb_define_module_under(mOSSL, "SSL");
 #endif
 	cSSLSession = rb_define_class_under(mSSL, "Session", rb_cObject);
Index: ext/openssl/ossl_pkey.c
===================================================================
--- ext/openssl/ossl_pkey.c	(revision 30089)
+++ ext/openssl/ossl_pkey.c	(revision 30090)
@@ -211,8 +211,8 @@
 void
 Init_ossl_pkey()
 {
-#if 0 /* let rdoc know about mOSSL */
-    mOSSL = rb_define_module("OpenSSL");
+#if 0
+    mOSSL = rb_define_module("OpenSSL"); /* let rdoc know about mOSSL */
 #endif
 
     mPKey = rb_define_module_under(mOSSL, "PKey");
Index: ext/openssl/ossl_pkey_dh.c
===================================================================
--- ext/openssl/ossl_pkey_dh.c	(revision 30089)
+++ ext/openssl/ossl_pkey_dh.c	(revision 30090)
@@ -489,8 +489,8 @@
 void
 Init_ossl_dh()
 {
-#if 0 /* let rdoc know about mOSSL and mPKey */
-    mOSSL = rb_define_module("OpenSSL");
+#if 0
+    mOSSL = rb_define_module("OpenSSL"); /* let rdoc know about mOSSL and mPKey */
     mPKey = rb_define_module_under(mOSSL, "PKey");
 #endif
 
Index: ext/openssl/ossl_rand.c
===================================================================
--- ext/openssl/ossl_rand.c	(revision 30089)
+++ ext/openssl/ossl_rand.c	(revision 30090)
@@ -181,8 +181,8 @@
 void
 Init_ossl_rand()
 {
-#if 0 /* let rdoc know about mOSSL */
-    mOSSL = rb_define_module("OpenSSL");
+#if 0
+    mOSSL = rb_define_module("OpenSSL"); /* let rdoc know about mOSSL */
 #endif
 
     mRandom = rb_define_module_under(mOSSL, "Random");

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]