Ruby  1.9.3p429(2013-05-15revision40747)
ossl.c
Go to the documentation of this file.
1 /*
2  * $Id: ossl.c 32538 2011-07-14 05:46:00Z nahi $
3  * 'OpenSSL for Ruby' project
4  * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz>
5  * All rights reserved.
6  */
7 /*
8  * This program is licenced under the same licence as Ruby.
9  * (See the file 'LICENCE'.)
10  */
11 #include "ossl.h"
12 #include <stdarg.h> /* for ossl_raise */
13 
14 /*
15  * String to HEXString conversion
16  */
17 int
18 string2hex(const unsigned char *buf, int buf_len, char **hexbuf, int *hexbuf_len)
19 {
20  static const char hex[]="0123456789abcdef";
21  int i, len = 2 * buf_len;
22 
23  if (buf_len < 0 || len < buf_len) { /* PARANOIA? */
24  return -1;
25  }
26  if (!hexbuf) { /* if no buf, return calculated len */
27  if (hexbuf_len) {
28  *hexbuf_len = len;
29  }
30  return len;
31  }
32  if (!(*hexbuf = OPENSSL_malloc(len + 1))) {
33  return -1;
34  }
35  for (i = 0; i < buf_len; i++) {
36  (*hexbuf)[2 * i] = hex[((unsigned char)buf[i]) >> 4];
37  (*hexbuf)[2 * i + 1] = hex[buf[i] & 0x0f];
38  }
39  (*hexbuf)[2 * i] = '\0';
40 
41  if (hexbuf_len) {
42  *hexbuf_len = len;
43  }
44  return len;
45 }
46 
47 /*
48  * Data Conversion
49  */
50 #define OSSL_IMPL_ARY2SK(name, type, expected_class, dup) \
51 STACK_OF(type) * \
52 ossl_##name##_ary2sk0(VALUE ary) \
53 { \
54  STACK_OF(type) *sk; \
55  VALUE val; \
56  type *x; \
57  int i; \
58  \
59  Check_Type(ary, T_ARRAY); \
60  sk = sk_##type##_new_null(); \
61  if (!sk) ossl_raise(eOSSLError, NULL); \
62  \
63  for (i = 0; i < RARRAY_LEN(ary); i++) { \
64  val = rb_ary_entry(ary, i); \
65  if (!rb_obj_is_kind_of(val, expected_class)) { \
66  sk_##type##_pop_free(sk, type##_free); \
67  ossl_raise(eOSSLError, "object in array not" \
68  " of class ##type##"); \
69  } \
70  x = dup(val); /* NEED TO DUP */ \
71  sk_##type##_push(sk, x); \
72  } \
73  return sk; \
74 } \
75  \
76 STACK_OF(type) * \
77 ossl_protect_##name##_ary2sk(VALUE ary, int *status) \
78 { \
79  return (STACK_OF(type)*)rb_protect( \
80  (VALUE(*)_((VALUE)))ossl_##name##_ary2sk0, \
81  ary, \
82  status); \
83 } \
84  \
85 STACK_OF(type) * \
86 ossl_##name##_ary2sk(VALUE ary) \
87 { \
88  STACK_OF(type) *sk; \
89  int status = 0; \
90  \
91  sk = ossl_protect_##name##_ary2sk(ary, &status); \
92  if (status) rb_jump_tag(status); \
93  \
94  return sk; \
95 }
97 
98 #define OSSL_IMPL_SK2ARY(name, type) \
99 VALUE \
100 ossl_##name##_sk2ary(STACK_OF(type) *sk) \
101 { \
102  type *t; \
103  int i, num; \
104  VALUE ary; \
105  \
106  if (!sk) { \
107  OSSL_Debug("empty sk!"); \
108  return Qnil; \
109  } \
110  num = sk_##type##_num(sk); \
111  if (num < 0) { \
112  OSSL_Debug("items in sk < -1???"); \
113  return rb_ary_new(); \
114  } \
115  ary = rb_ary_new2(num); \
116  \
117  for (i=0; i<num; i++) { \
118  t = sk_##type##_value(sk, i); \
119  rb_ary_push(ary, ossl_##name##_new(t)); \
120  } \
121  return ary; \
122 }
123 OSSL_IMPL_SK2ARY(x509, X509)
124 OSSL_IMPL_SK2ARY(x509crl, X509_CRL)
125 OSSL_IMPL_SK2ARY(x509name, X509_NAME)
126 
127 static VALUE
129 {
130  return rb_str_new(0, size);
131 }
132 
133 VALUE
134 ossl_buf2str(char *buf, int len)
135 {
136  VALUE str;
137  int status = 0;
138 
139  str = rb_protect((VALUE(*)_((VALUE)))ossl_str_new, len, &status);
140  if(!NIL_P(str)) memcpy(RSTRING_PTR(str), buf, len);
141  OPENSSL_free(buf);
142  if(status) rb_jump_tag(status);
143 
144  return str;
145 }
146 
147 /*
148  * our default PEM callback
149  */
150 static VALUE
152 {
153  VALUE pass;
154 
155  pass = rb_yield(flag);
156  SafeStringValue(pass);
157 
158  return pass;
159 }
160 
161 int
162 ossl_pem_passwd_cb(char *buf, int max_len, int flag, void *pwd)
163 {
164  int len, status = 0;
165  VALUE rflag, pass;
166 
167  if (pwd || !rb_block_given_p())
168  return PEM_def_callback(buf, max_len, flag, pwd);
169 
170  while (1) {
171  /*
172  * when the flag is nonzero, this passphrase
173  * will be used to perform encryption; otherwise it will
174  * be used to perform decryption.
175  */
176  rflag = flag ? Qtrue : Qfalse;
177  pass = rb_protect(ossl_pem_passwd_cb0, rflag, &status);
178  if (status) return -1; /* exception was raised. */
179  len = RSTRING_LENINT(pass);
180  if (len < 4) { /* 4 is OpenSSL hardcoded limit */
181  rb_warning("password must be longer than 4 bytes");
182  continue;
183  }
184  if (len > max_len) {
185  rb_warning("password must be shorter then %d bytes", max_len-1);
186  continue;
187  }
188  memcpy(buf, RSTRING_PTR(pass), len);
189  break;
190  }
191  return len;
192 }
193 
194 /*
195  * Verify callback
196  */
198 
199 VALUE
201 {
202  return rb_funcall(args->proc, rb_intern("call"), 2,
203  args->preverify_ok, args->store_ctx);
204 }
205 
206 int
207 ossl_verify_cb(int ok, X509_STORE_CTX *ctx)
208 {
209  VALUE proc, rctx, ret;
210  struct ossl_verify_cb_args args;
211  int state = 0;
212 
213  proc = (VALUE)X509_STORE_CTX_get_ex_data(ctx, ossl_verify_cb_idx);
214  if ((void*)proc == 0)
215  proc = (VALUE)X509_STORE_get_ex_data(ctx->ctx, ossl_verify_cb_idx);
216  if ((void*)proc == 0)
217  return ok;
218  if (!NIL_P(proc)) {
220  (VALUE)ctx, &state);
221  ret = Qfalse;
222  if (!state) {
223  args.proc = proc;
224  args.preverify_ok = ok ? Qtrue : Qfalse;
225  args.store_ctx = rctx;
226  ret = rb_protect((VALUE(*)(VALUE))ossl_call_verify_cb_proc, (VALUE)&args, &state);
228  if (state) {
229  rb_warn("exception in verify_callback is ignored");
230  }
231  }
232  if (ret == Qtrue) {
233  X509_STORE_CTX_set_error(ctx, X509_V_OK);
234  ok = 1;
235  }
236  else{
237  if (X509_STORE_CTX_get_error(ctx) == X509_V_OK) {
238  X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REJECTED);
239  }
240  ok = 0;
241  }
242  }
243 
244  return ok;
245 }
246 
247 /*
248  * main module
249  */
251 
252 /*
253  * OpenSSLError < StandardError
254  */
256 
257 /*
258  * Convert to DER string
259  */
261 
262 VALUE
264 {
265  VALUE tmp;
266 
267  tmp = rb_funcall(obj, ossl_s_to_der, 0);
268  StringValue(tmp);
269 
270  return tmp;
271 }
272 
273 VALUE
275 {
276  if(rb_respond_to(obj, ossl_s_to_der))
277  return ossl_to_der(obj);
278  return obj;
279 }
280 
281 /*
282  * Errors
283  */
284 static VALUE
285 ossl_make_error(VALUE exc, const char *fmt, va_list args)
286 {
287  char buf[BUFSIZ];
288  const char *msg;
289  long e;
290  int len = 0;
291 
292 #ifdef HAVE_ERR_PEEK_LAST_ERROR
293  e = ERR_peek_last_error();
294 #else
295  e = ERR_peek_error();
296 #endif
297  if (fmt) {
298  len = vsnprintf(buf, BUFSIZ, fmt, args);
299  }
300  if (len < BUFSIZ && e) {
301  if (dOSSL == Qtrue) /* FULL INFO */
302  msg = ERR_error_string(e, NULL);
303  else
304  msg = ERR_reason_error_string(e);
305  len += snprintf(buf+len, BUFSIZ-len, "%s%s", (len ? ": " : ""), msg);
306  }
307  if (dOSSL == Qtrue){ /* show all errors on the stack */
308  while ((e = ERR_get_error()) != 0){
309  rb_warn("error on stack: %s", ERR_error_string(e, NULL));
310  }
311  }
312  ERR_clear_error();
313 
314  if(len > BUFSIZ) len = rb_long2int(strlen(buf));
315  return rb_exc_new(exc, buf, len);
316 }
317 
318 void
319 ossl_raise(VALUE exc, const char *fmt, ...)
320 {
321  va_list args;
322  VALUE err;
323  va_start(args, fmt);
324  err = ossl_make_error(exc, fmt, args);
325  va_end(args);
326  rb_exc_raise(err);
327 }
328 
329 VALUE
330 ossl_exc_new(VALUE exc, const char *fmt, ...)
331 {
332  va_list args;
333  VALUE err;
334  va_start(args, fmt);
335  err = ossl_make_error(exc, fmt, args);
336  va_end(args);
337  return err;
338 }
339 
340 /*
341  * call-seq:
342  * OpenSSL.errors -> [String...]
343  *
344  * See any remaining errors held in queue.
345  *
346  * Any errors you see here are probably due to a bug in ruby's OpenSSL implementation.
347  */
348 VALUE
350 {
351  VALUE ary;
352  long e;
353 
354  ary = rb_ary_new();
355  while ((e = ERR_get_error()) != 0){
356  rb_ary_push(ary, rb_str_new2(ERR_error_string(e, NULL)));
357  }
358 
359  return ary;
360 }
361 
362 /*
363  * Debug
364  */
366 
367 #if !defined(HAVE_VA_ARGS_MACRO)
368 void
369 ossl_debug(const char *fmt, ...)
370 {
371  va_list args;
372 
373  if (dOSSL == Qtrue) {
374  fprintf(stderr, "OSSL_DEBUG: ");
375  va_start(args, fmt);
376  vfprintf(stderr, fmt, args);
377  va_end(args);
378  fprintf(stderr, " [CONTEXT N/A]\n");
379  }
380 }
381 #endif
382 
383 /*
384  * call-seq:
385  * OpenSSL.debug -> true | false
386  */
387 static VALUE
389 {
390  return dOSSL;
391 }
392 
393 /*
394  * call-seq:
395  * OpenSSL.debug = boolean -> boolean
396  *
397  * Turns on or off CRYPTO_MEM_CHECK.
398  * Also shows some debugging message on stderr.
399  */
400 static VALUE
402 {
403  VALUE old = dOSSL;
404  dOSSL = val;
405 
406  if (old != dOSSL) {
407  if (dOSSL == Qtrue) {
408  CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
409  fprintf(stderr, "OSSL_DEBUG: IS NOW ON!\n");
410  } else if (old == Qtrue) {
411  CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_OFF);
412  fprintf(stderr, "OSSL_DEBUG: IS NOW OFF!\n");
413  }
414  }
415  return val;
416 }
417 
418 /*
419  * OpenSSL provides SSL, TLS and general purpose cryptography. It wraps the
420  * OpenSSL[http://www.openssl.org/] library.
421  *
422  * = Examples
423  *
424  * All examples assume you have loaded OpenSSL with:
425  *
426  * require 'openssl'
427  *
428  * These examples build atop each other. For example the key created in the
429  * next is used in throughout these examples.
430  *
431  * == Keys
432  *
433  * === Creating a Key
434  *
435  * This example creates a 2048 bit RSA keypair and writes it to the current
436  * directory.
437  *
438  * key = OpenSSL::PKey::RSA.new 2048
439  *
440  * open 'private_key.pem', 'w' do |io| io.write key.to_pem end
441  * open 'public_key.pem', 'w' do |io| io.write key.public_key.to_pem end
442  *
443  * === Exporting a Key
444  *
445  * Keys saved to disk without encryption are not secure as anyone who gets
446  * ahold of the key may use it unless it is encrypted. In order to securely
447  * export a key you may export it with a pass phrase.
448  *
449  * cipher = OpenSSL::Cipher::Cipher.new 'AES-128-CBC'
450  * pass_phrase = 'my secure pass phrase goes here'
451  *
452  * key_secure = key.export cipher, pass_phrase
453  *
454  * open 'private.secure.pem', 'w' do |io|
455  * io.write key_secure
456  * end
457  *
458  * OpenSSL::Cipher.ciphers returns a list of available ciphers.
459  *
460  * === Loading a Key
461  *
462  * A key can also be loaded from a file.
463  *
464  * key2 = OpenSSL::PKey::RSA.new File.read 'private_key.pem'
465  * key2.public? # => true
466  *
467  * or
468  *
469  * key3 = OpenSSL::PKey::RSA.new File.read 'public_key.pem'
470  * key3.private? # => false
471  *
472  * === Loading an Encrypted Key
473  *
474  * OpenSSL will prompt you for your pass phrase when loading an encrypted key.
475  * If you will not be able to type in the pass phrase you may provide it when
476  * loading the key:
477  *
478  * key4_pem = File.read 'private.secure.pem'
479  * key4 = OpenSSL::PKey::RSA.new key4_pem, pass_phrase
480  *
481  * == RSA Encryption
482  *
483  * RSA provides ecryption and decryption using the public and private keys.
484  * You can use a variety of padding methods depending upon the intended use of
485  * encrypted data.
486  *
487  * === Encryption
488  *
489  * Documents encrypted with the public key can only be decrypted with the
490  * private key.
491  *
492  * public_encrypted = key.public_encrypt 'top secret document'
493  *
494  * Documents encrypted with the private key can only be decrypted with the
495  * public key.
496  *
497  * private_encrypted = key.private_encrypt 'public release document'
498  *
499  * === Decryption
500  *
501  * Use the opposite key type do decrypt the document
502  *
503  * top_secret = key.public_decrypt public_encrypted
504  *
505  * public_release = key.private_decrypt private_encrypted
506  *
507  * == PKCS #5 Password-based Encryption
508  *
509  * PKCS #5 is a password-based encryption standard documented at
510  * RFC2898[http://www.ietf.org/rfc/rfc2898.txt]. It allows a short password or
511  * passphrase to be used to create a secure encryption key.
512  *
513  * PKCS #5 uses a Cipher, a pass phrase and a salt to generate an encryption
514  * key.
515  *
516  * pass_phrase = 'my secure pass phrase goes here'
517  * salt = '8 octets'
518  *
519  * === Encryption
520  *
521  * First set up the cipher for encryption
522  *
523  * encrypter = OpenSSL::Cipher::Cipher.new 'AES-128-CBC'
524  * encrypter.encrypt
525  * encrypter.pkcs5_keyivgen pass_phrase, salt
526  *
527  * Then pass the data you want to encrypt through
528  *
529  * encrypted = encrypter.update 'top secret document'
530  * encrypted << encrypter.final
531  *
532  * === Decryption
533  *
534  * Use a new Cipher instance set up for decryption
535  *
536  * decrypter = OpenSSL::Cipher::Cipher.new 'AES-128-CBC'
537  * decrypter.decrypt
538  * decrypter.pkcs5_keyivgen pass_phrase, salt
539  *
540  * Then pass the data you want to decrypt through
541  *
542  * plain = decrypter.update encrypted
543  * plain << decrypter.final
544  *
545  * == X509 Certificates
546  *
547  * === Creating a Certificate
548  *
549  * This example creates a self-signed certificate using an RSA key and a SHA1
550  * signature.
551  *
552  * name = OpenSSL::X509::Name.parse 'CN=nobody/DC=example'
553  *
554  * cert = OpenSSL::X509::Certificate.new
555  * cert.version = 2
556  * cert.serial = 0
557  * cert.not_before = Time.now
558  * cert.not_after = Time.now + 3600
559  *
560  * cert.public_key = key.public_key
561  * cert.subject = name
562  *
563  * === Certificate Extensions
564  *
565  * You can add extensions to the certificate with
566  * OpenSSL::SSL::ExtensionFactory to indicate the purpose of the certificate.
567  *
568  * extension_factory = OpenSSL::X509::ExtensionFactory.new nil, cert
569  *
570  * extension_factory.create_extension 'basicConstraints', 'CA:FALSE'
571  * extension_factory.create_extension 'keyUsage',
572  * 'keyEncipherment,dataEncipherment,digitalSignature'
573  * extension_factory.create_extension 'subjectKeyIdentifier', 'hash'
574  *
575  * === Signing a Certificate
576  *
577  * To sign a certificate set the issuer and use OpenSSL::X509::Certificate#sign
578  * with a digest algorithm. This creates a self-signed cert because we're using
579  * the same name and key to sign the certificate as was used to create the
580  * certificate.
581  *
582  * cert.issuer = name
583  * cert.sign key, OpenSSL::Digest::SHA1.new
584  *
585  * open 'certificate.pem', 'w' do |io| io.write cert.to_pem end
586  *
587  * === Loading a Certificate
588  *
589  * Like a key, a cert can also be loaded from a file.
590  *
591  * cert2 = OpenSSL::X509::Certificate.new File.read 'certificate.pem'
592  *
593  * === Verifying a Certificate
594  *
595  * Certificate#verify will return true when a certificate was signed with the
596  * given public key.
597  *
598  * raise 'certificate can not be verified' unless cert2.verify key
599  *
600  * == Certificate Authority
601  *
602  * A certificate authority (CA) is a trusted third party that allows you to
603  * verify the ownership of unknown certificates. The CA issues key signatures
604  * that indicate it trusts the user of that key. A user encountering the key
605  * can verify the signature by using the CA's public key.
606  *
607  * === CA Key
608  *
609  * CA keys are valuable, so we encrypt and save it to disk and make sure it is
610  * not readable by other users.
611  *
612  * ca_key = OpenSSL::PKey::RSA.new 2048
613  *
614  * cipher = OpenSSL::Cipher::Cipher.new 'AES-128-CBC'
615  *
616  * open 'ca_key.pem', 'w', 0400 do |io|
617  * io.write key.export(cipher, pass_phrase)
618  * end
619  *
620  * === CA Certificate
621  *
622  * A CA certificate is created the same way we created a certificate above, but
623  * with different extensions.
624  *
625  * ca_name = OpenSSL::X509::Name.parse 'CN=ca/DC=example'
626  *
627  * ca_cert = OpenSSL::X509::Certificate.new
628  * ca_cert.serial = 0
629  * ca_cert.version = 2
630  * ca_cert.not_before = Time.now
631  * ca_cert.not_after = Time.now + 86400
632  *
633  * ca_cert.public_key = ca_key.public_key
634  * ca_cert.subject = ca_name
635  * ca_cert.issuer = ca_name
636  *
637  * extension_factory = OpenSSL::X509::ExtensionFactory.new
638  * extension_factory.subject_certificate = ca_cert
639  * extension_factory.issuer_certificate = ca_cert
640  *
641  * extension_factory.create_extension 'subjectKeyIdentifier', 'hash'
642  *
643  * This extension indicates the CA's key may be used as a CA.
644  *
645  * extension_factory.create_extension 'basicConstraints', 'CA:TRUE', true
646  *
647  * This extension indicates the CA's key may be used to verify signatures on
648  * both certificates and certificate revocations.
649  *
650  * extension_factory.create_extension 'keyUsage', 'cRLSign,keyCertSign', true
651  *
652  * Root CA certificates are self-signed.
653  *
654  * ca_cert.sign ca_key, OpenSSL::Digest::SHA1.new
655  *
656  * The CA certificate is saved to disk so it may be distributed to all the
657  * users of the keys this CA will sign.
658  *
659  * open 'ca_cert.pem', 'w' do |io|
660  * io.write ca_cert.to_pem
661  * end
662  *
663  * === Certificate Signing Request
664  *
665  * The CA signs keys through a Certificate Signing Request (CSR). The CSR
666  * contains the information necessary to identify the key.
667  *
668  * csr = OpenSSL::X509::Request.new
669  * csr.version = 0
670  * csr.subject = name
671  * csr.public_key = key.public_key
672  * csr.sign key, OpenSSL::Digest::SHA1.new
673  *
674  * A CSR is saved to disk and sent to the CA for signing.
675  *
676  * open 'csr.pem', 'w' do |io|
677  * io.write csr.to_pem
678  * end
679  *
680  * === Creating a Certificate from a CSR
681  *
682  * Upon receiving a CSR the CA will verify it before signing it. A minimal
683  * verification would be to check the CSR's signature.
684  *
685  * csr = OpenSSL::X509::Request.new File.read 'csr.pem'
686  *
687  * raise 'CSR can not be verified' unless csr.verify csr.public_key
688  *
689  * After verification a certificate is created, marked for various usages,
690  * signed with the CA key and returned to the requester.
691  *
692  * csr_cert = OpenSSL::X509::Certificate.new
693  * csr_cert.serial = 0
694  * csr_cert.version = 2
695  * csr_cert.not_before = Time.now
696  * csr_cert.not_after = Time.now + 600
697  *
698  * csr_cert.subject = csr.subject
699  * csr_cert.public_key = csr.public_key
700  * csr_cert.issuer = ca_cert.subject
701  *
702  * extension_factory = OpenSSL::X509::ExtensionFactory.new
703  * extension_factory.subject_certificate = csr_cert
704  * extension_factory.issuer_certificate = ca_cert
705  *
706  * extension_factory.create_extension 'basicConstraints', 'CA:FALSE'
707  * extension_factory.create_extension 'keyUsage',
708  * 'keyEncipherment,dataEncipherment,digitalSignature'
709  * extension_factory.create_extension 'subjectKeyIdentifier', 'hash'
710  *
711  * csr_cert.sign ca_key, OpenSSL::Digest::SHA1.new
712  *
713  * open 'csr_cert.pem', 'w' do |io|
714  * io.write csr_cert.to_pem
715  * end
716  *
717  * == SSL and TLS Connections
718  *
719  * Using our created key and certificate we can create an SSL or TLS connection.
720  * An SSLContext is used to set up an SSL session.
721  *
722  * context = OpenSSL::SSL::SSLContext.new
723  *
724  * === SSL Server
725  *
726  * An SSL server requires the certificate and private key to communicate
727  * securely with its clients:
728  *
729  * context.cert = cert
730  * context.key = key
731  *
732  * Then create an SSLServer with a TCP server socket and the context. Use the
733  * SSLServer like an ordinary TCP server.
734  *
735  * require 'socket'
736  *
737  * tcp_server = TCPServer.new 5000
738  * ssl_server = OpenSSL::SSL::SSLServer.new tcp_server, context
739  *
740  * loop do
741  * ssl_connection = ssl_server.accept
742  *
743  * data = connection.gets
744  *
745  * response = "I got #{data.dump}"
746  * puts response
747  *
748  * connection.puts "I got #{data.dump}"
749  * connection.close
750  * end
751  *
752  * === SSL client
753  *
754  * An SSL client is created with a TCP socket and the context.
755  * SSLSocket#connect must be called to initiate the SSL handshake and start
756  * encryption. A key and certificate are not required for the client socket.
757  *
758  * require 'socket'
759  *
760  * tcp_client = TCPSocket.new 'localhost', 5000
761  * ssl_client = OpenSSL::SSL::SSLSocket.new client_socket, context
762  * ssl_client.connect
763  *
764  * ssl_client.puts "hello server!"
765  * puts ssl_client.gets
766  *
767  * === Peer Verification
768  *
769  * An unverified SSL connection does not provide much security. For enhanced
770  * security the client or server can verify the certificate of its peer.
771  *
772  * The client can be modified to verify the server's certificate against the
773  * certificate authority's certificate:
774  *
775  * context.ca_file = 'ca_cert.pem'
776  * context.verify_mode = OpenSSL::SSL::VERIFY_PEER
777  *
778  * require 'socket'
779  *
780  * tcp_client = TCPSocket.new 'localhost', 5000
781  * ssl_client = OpenSSL::SSL::SSLSocket.new client_socket, context
782  * ssl_client.connect
783  *
784  * ssl_client.puts "hello server!"
785  * puts ssl_client.gets
786  *
787  * If the server certificate is invalid or <tt>context.ca_file</tt> is not set
788  * when verifying peers an OpenSSL::SSL::SSLError will be raised.
789  *
790  */
791 void
793 {
794  /*
795  * Init timezone info
796  */
797 #if 0
798  tzset();
799 #endif
800 
801  /*
802  * Init all digests, ciphers
803  */
804  /* CRYPTO_malloc_init(); */
805  /* ENGINE_load_builtin_engines(); */
806  OpenSSL_add_ssl_algorithms();
807  OpenSSL_add_all_algorithms();
808  ERR_load_crypto_strings();
809  SSL_load_error_strings();
810 
811  /*
812  * FIXME:
813  * On unload do:
814  */
815 #if 0
816  CONF_modules_unload(1);
817  destroy_ui_method();
818  EVP_cleanup();
819  ENGINE_cleanup();
820  CRYPTO_cleanup_all_ex_data();
821  ERR_remove_state(0);
822  ERR_free_strings();
823 #endif
824 
825  /*
826  * Init main module
827  */
828  mOSSL = rb_define_module("OpenSSL");
829 
830  /*
831  * OpenSSL ruby extension version
832  */
833  rb_define_const(mOSSL, "VERSION", rb_str_new2(OSSL_VERSION));
834 
835  /*
836  * Version of OpenSSL the ruby OpenSSL extension was built with
837  */
838  rb_define_const(mOSSL, "OPENSSL_VERSION", rb_str_new2(OPENSSL_VERSION_TEXT));
839  /*
840  * Version number of OpenSSL the ruby OpenSSL extension was built with
841  * (base 16)
842  */
843  rb_define_const(mOSSL, "OPENSSL_VERSION_NUMBER", INT2NUM(OPENSSL_VERSION_NUMBER));
844 
845  /*
846  * Generic error,
847  * common for all classes under OpenSSL module
848  */
849  eOSSLError = rb_define_class_under(mOSSL,"OpenSSLError",rb_eStandardError);
850 
851  /*
852  * Verify callback Proc index for ext-data
853  */
854  if ((ossl_verify_cb_idx = X509_STORE_CTX_get_ex_new_index(0, (void *)"ossl_verify_cb_idx", 0, 0, 0)) < 0)
855  ossl_raise(eOSSLError, "X509_STORE_CTX_get_ex_new_index");
856 
857  /*
858  * Init debug core
859  */
860  dOSSL = Qfalse;
861  rb_define_module_function(mOSSL, "debug", ossl_debug_get, 0);
862  rb_define_module_function(mOSSL, "debug=", ossl_debug_set, 1);
863  rb_define_module_function(mOSSL, "errors", ossl_get_errors, 0);
864 
865  /*
866  * Get ID of to_der
867  */
868  ossl_s_to_der = rb_intern("to_der");
869 
870  /*
871  * Init components
872  */
873  Init_ossl_bn();
877  Init_ossl_hmac();
880  Init_ossl_pkcs7();
881  Init_ossl_pkcs5();
882  Init_ossl_pkey();
883  Init_ossl_rand();
884  Init_ossl_ssl();
885  Init_ossl_x509();
886  Init_ossl_ocsp();
888  Init_ossl_asn1();
889 }
890 
891 #if defined(OSSL_DEBUG)
892 /*
893  * Check if all symbols are OK with 'make LDSHARED=gcc all'
894  */
895 int
896 main(int argc, char *argv[])
897 {
898  return 0;
899 }
900 #endif /* OSSL_DEBUG */
901 
902