Ruby  1.9.3p551(2014-11-13revision48407)
ossl.c
Go to the documentation of this file.
1 /*
2  * $Id: ossl.c 45485 2014-03-31 06:38:23Z usa $
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  VALUE str = Qnil;
288  const char *msg;
289  long e;
290 
291 #ifdef HAVE_ERR_PEEK_LAST_ERROR
292  e = ERR_peek_last_error();
293 #else
294  e = ERR_peek_error();
295 #endif
296  if (fmt) {
297  str = rb_vsprintf(fmt, args);
298  }
299  if (e) {
300  if (dOSSL == Qtrue) /* FULL INFO */
301  msg = ERR_error_string(e, NULL);
302  else
303  msg = ERR_reason_error_string(e);
304  if (NIL_P(str)) {
305  if (msg) str = rb_str_new_cstr(msg);
306  }
307  else {
308  if (RSTRING_LEN(str)) rb_str_cat2(str, ": ");
309  rb_str_cat2(str, msg ? msg : "(null)");
310  }
311  }
312  if (dOSSL == Qtrue){ /* show all errors on the stack */
313  while ((e = ERR_get_error()) != 0){
314  rb_warn("error on stack: %s", ERR_error_string(e, NULL));
315  }
316  }
317  ERR_clear_error();
318 
319  if (NIL_P(str)) str = rb_str_new(0, 0);
320  return rb_exc_new3(exc, str);
321 }
322 
323 void
324 ossl_raise(VALUE exc, const char *fmt, ...)
325 {
326  va_list args;
327  VALUE err;
328  va_start(args, fmt);
329  err = ossl_make_error(exc, fmt, args);
330  va_end(args);
331  rb_exc_raise(err);
332 }
333 
334 VALUE
335 ossl_exc_new(VALUE exc, const char *fmt, ...)
336 {
337  va_list args;
338  VALUE err;
339  va_start(args, fmt);
340  err = ossl_make_error(exc, fmt, args);
341  va_end(args);
342  return err;
343 }
344 
345 /*
346  * call-seq:
347  * OpenSSL.errors -> [String...]
348  *
349  * See any remaining errors held in queue.
350  *
351  * Any errors you see here are probably due to a bug in ruby's OpenSSL implementation.
352  */
353 VALUE
355 {
356  VALUE ary;
357  long e;
358 
359  ary = rb_ary_new();
360  while ((e = ERR_get_error()) != 0){
361  rb_ary_push(ary, rb_str_new2(ERR_error_string(e, NULL)));
362  }
363 
364  return ary;
365 }
366 
367 /*
368  * Debug
369  */
371 
372 #if !defined(HAVE_VA_ARGS_MACRO)
373 void
374 ossl_debug(const char *fmt, ...)
375 {
376  va_list args;
377 
378  if (dOSSL == Qtrue) {
379  fprintf(stderr, "OSSL_DEBUG: ");
380  va_start(args, fmt);
381  vfprintf(stderr, fmt, args);
382  va_end(args);
383  fprintf(stderr, " [CONTEXT N/A]\n");
384  }
385 }
386 #endif
387 
388 /*
389  * call-seq:
390  * OpenSSL.debug -> true | false
391  */
392 static VALUE
394 {
395  return dOSSL;
396 }
397 
398 /*
399  * call-seq:
400  * OpenSSL.debug = boolean -> boolean
401  *
402  * Turns on or off CRYPTO_MEM_CHECK.
403  * Also shows some debugging message on stderr.
404  */
405 static VALUE
407 {
408  VALUE old = dOSSL;
409  dOSSL = val;
410 
411  if (old != dOSSL) {
412  if (dOSSL == Qtrue) {
413  CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
414  fprintf(stderr, "OSSL_DEBUG: IS NOW ON!\n");
415  } else if (old == Qtrue) {
416  CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_OFF);
417  fprintf(stderr, "OSSL_DEBUG: IS NOW OFF!\n");
418  }
419  }
420  return val;
421 }
422 
423 /*
424  * OpenSSL provides SSL, TLS and general purpose cryptography. It wraps the
425  * OpenSSL[http://www.openssl.org/] library.
426  *
427  * = Examples
428  *
429  * All examples assume you have loaded OpenSSL with:
430  *
431  * require 'openssl'
432  *
433  * These examples build atop each other. For example the key created in the
434  * next is used in throughout these examples.
435  *
436  * == Keys
437  *
438  * === Creating a Key
439  *
440  * This example creates a 2048 bit RSA keypair and writes it to the current
441  * directory.
442  *
443  * key = OpenSSL::PKey::RSA.new 2048
444  *
445  * open 'private_key.pem', 'w' do |io| io.write key.to_pem end
446  * open 'public_key.pem', 'w' do |io| io.write key.public_key.to_pem end
447  *
448  * === Exporting a Key
449  *
450  * Keys saved to disk without encryption are not secure as anyone who gets
451  * ahold of the key may use it unless it is encrypted. In order to securely
452  * export a key you may export it with a pass phrase.
453  *
454  * cipher = OpenSSL::Cipher::Cipher.new 'AES-128-CBC'
455  * pass_phrase = 'my secure pass phrase goes here'
456  *
457  * key_secure = key.export cipher, pass_phrase
458  *
459  * open 'private.secure.pem', 'w' do |io|
460  * io.write key_secure
461  * end
462  *
463  * OpenSSL::Cipher.ciphers returns a list of available ciphers.
464  *
465  * === Loading a Key
466  *
467  * A key can also be loaded from a file.
468  *
469  * key2 = OpenSSL::PKey::RSA.new File.read 'private_key.pem'
470  * key2.public? # => true
471  *
472  * or
473  *
474  * key3 = OpenSSL::PKey::RSA.new File.read 'public_key.pem'
475  * key3.private? # => false
476  *
477  * === Loading an Encrypted Key
478  *
479  * OpenSSL will prompt you for your pass phrase when loading an encrypted key.
480  * If you will not be able to type in the pass phrase you may provide it when
481  * loading the key:
482  *
483  * key4_pem = File.read 'private.secure.pem'
484  * key4 = OpenSSL::PKey::RSA.new key4_pem, pass_phrase
485  *
486  * == RSA Encryption
487  *
488  * RSA provides ecryption and decryption using the public and private keys.
489  * You can use a variety of padding methods depending upon the intended use of
490  * encrypted data.
491  *
492  * === Encryption
493  *
494  * Documents encrypted with the public key can only be decrypted with the
495  * private key.
496  *
497  * public_encrypted = key.public_encrypt 'top secret document'
498  *
499  * Documents encrypted with the private key can only be decrypted with the
500  * public key.
501  *
502  * private_encrypted = key.private_encrypt 'public release document'
503  *
504  * === Decryption
505  *
506  * Use the opposite key type do decrypt the document
507  *
508  * top_secret = key.public_decrypt public_encrypted
509  *
510  * public_release = key.private_decrypt private_encrypted
511  *
512  * == PKCS #5 Password-based Encryption
513  *
514  * PKCS #5 is a password-based encryption standard documented at
515  * RFC2898[http://www.ietf.org/rfc/rfc2898.txt]. It allows a short password or
516  * passphrase to be used to create a secure encryption key.
517  *
518  * PKCS #5 uses a Cipher, a pass phrase and a salt to generate an encryption
519  * key.
520  *
521  * pass_phrase = 'my secure pass phrase goes here'
522  * salt = '8 octets'
523  *
524  * === Encryption
525  *
526  * First set up the cipher for encryption
527  *
528  * encrypter = OpenSSL::Cipher::Cipher.new 'AES-128-CBC'
529  * encrypter.encrypt
530  * encrypter.pkcs5_keyivgen pass_phrase, salt
531  *
532  * Then pass the data you want to encrypt through
533  *
534  * encrypted = encrypter.update 'top secret document'
535  * encrypted << encrypter.final
536  *
537  * === Decryption
538  *
539  * Use a new Cipher instance set up for decryption
540  *
541  * decrypter = OpenSSL::Cipher::Cipher.new 'AES-128-CBC'
542  * decrypter.decrypt
543  * decrypter.pkcs5_keyivgen pass_phrase, salt
544  *
545  * Then pass the data you want to decrypt through
546  *
547  * plain = decrypter.update encrypted
548  * plain << decrypter.final
549  *
550  * == X509 Certificates
551  *
552  * === Creating a Certificate
553  *
554  * This example creates a self-signed certificate using an RSA key and a SHA1
555  * signature.
556  *
557  * name = OpenSSL::X509::Name.parse 'CN=nobody/DC=example'
558  *
559  * cert = OpenSSL::X509::Certificate.new
560  * cert.version = 2
561  * cert.serial = 0
562  * cert.not_before = Time.now
563  * cert.not_after = Time.now + 3600
564  *
565  * cert.public_key = key.public_key
566  * cert.subject = name
567  *
568  * === Certificate Extensions
569  *
570  * You can add extensions to the certificate with
571  * OpenSSL::SSL::ExtensionFactory to indicate the purpose of the certificate.
572  *
573  * extension_factory = OpenSSL::X509::ExtensionFactory.new nil, cert
574  *
575  * extension_factory.create_extension 'basicConstraints', 'CA:FALSE'
576  * extension_factory.create_extension 'keyUsage',
577  * 'keyEncipherment,dataEncipherment,digitalSignature'
578  * extension_factory.create_extension 'subjectKeyIdentifier', 'hash'
579  *
580  * === Signing a Certificate
581  *
582  * To sign a certificate set the issuer and use OpenSSL::X509::Certificate#sign
583  * with a digest algorithm. This creates a self-signed cert because we're using
584  * the same name and key to sign the certificate as was used to create the
585  * certificate.
586  *
587  * cert.issuer = name
588  * cert.sign key, OpenSSL::Digest::SHA1.new
589  *
590  * open 'certificate.pem', 'w' do |io| io.write cert.to_pem end
591  *
592  * === Loading a Certificate
593  *
594  * Like a key, a cert can also be loaded from a file.
595  *
596  * cert2 = OpenSSL::X509::Certificate.new File.read 'certificate.pem'
597  *
598  * === Verifying a Certificate
599  *
600  * Certificate#verify will return true when a certificate was signed with the
601  * given public key.
602  *
603  * raise 'certificate can not be verified' unless cert2.verify key
604  *
605  * == Certificate Authority
606  *
607  * A certificate authority (CA) is a trusted third party that allows you to
608  * verify the ownership of unknown certificates. The CA issues key signatures
609  * that indicate it trusts the user of that key. A user encountering the key
610  * can verify the signature by using the CA's public key.
611  *
612  * === CA Key
613  *
614  * CA keys are valuable, so we encrypt and save it to disk and make sure it is
615  * not readable by other users.
616  *
617  * ca_key = OpenSSL::PKey::RSA.new 2048
618  *
619  * cipher = OpenSSL::Cipher::Cipher.new 'AES-128-CBC'
620  *
621  * open 'ca_key.pem', 'w', 0400 do |io|
622  * io.write key.export(cipher, pass_phrase)
623  * end
624  *
625  * === CA Certificate
626  *
627  * A CA certificate is created the same way we created a certificate above, but
628  * with different extensions.
629  *
630  * ca_name = OpenSSL::X509::Name.parse 'CN=ca/DC=example'
631  *
632  * ca_cert = OpenSSL::X509::Certificate.new
633  * ca_cert.serial = 0
634  * ca_cert.version = 2
635  * ca_cert.not_before = Time.now
636  * ca_cert.not_after = Time.now + 86400
637  *
638  * ca_cert.public_key = ca_key.public_key
639  * ca_cert.subject = ca_name
640  * ca_cert.issuer = ca_name
641  *
642  * extension_factory = OpenSSL::X509::ExtensionFactory.new
643  * extension_factory.subject_certificate = ca_cert
644  * extension_factory.issuer_certificate = ca_cert
645  *
646  * extension_factory.create_extension 'subjectKeyIdentifier', 'hash'
647  *
648  * This extension indicates the CA's key may be used as a CA.
649  *
650  * extension_factory.create_extension 'basicConstraints', 'CA:TRUE', true
651  *
652  * This extension indicates the CA's key may be used to verify signatures on
653  * both certificates and certificate revocations.
654  *
655  * extension_factory.create_extension 'keyUsage', 'cRLSign,keyCertSign', true
656  *
657  * Root CA certificates are self-signed.
658  *
659  * ca_cert.sign ca_key, OpenSSL::Digest::SHA1.new
660  *
661  * The CA certificate is saved to disk so it may be distributed to all the
662  * users of the keys this CA will sign.
663  *
664  * open 'ca_cert.pem', 'w' do |io|
665  * io.write ca_cert.to_pem
666  * end
667  *
668  * === Certificate Signing Request
669  *
670  * The CA signs keys through a Certificate Signing Request (CSR). The CSR
671  * contains the information necessary to identify the key.
672  *
673  * csr = OpenSSL::X509::Request.new
674  * csr.version = 0
675  * csr.subject = name
676  * csr.public_key = key.public_key
677  * csr.sign key, OpenSSL::Digest::SHA1.new
678  *
679  * A CSR is saved to disk and sent to the CA for signing.
680  *
681  * open 'csr.pem', 'w' do |io|
682  * io.write csr.to_pem
683  * end
684  *
685  * === Creating a Certificate from a CSR
686  *
687  * Upon receiving a CSR the CA will verify it before signing it. A minimal
688  * verification would be to check the CSR's signature.
689  *
690  * csr = OpenSSL::X509::Request.new File.read 'csr.pem'
691  *
692  * raise 'CSR can not be verified' unless csr.verify csr.public_key
693  *
694  * After verification a certificate is created, marked for various usages,
695  * signed with the CA key and returned to the requester.
696  *
697  * csr_cert = OpenSSL::X509::Certificate.new
698  * csr_cert.serial = 0
699  * csr_cert.version = 2
700  * csr_cert.not_before = Time.now
701  * csr_cert.not_after = Time.now + 600
702  *
703  * csr_cert.subject = csr.subject
704  * csr_cert.public_key = csr.public_key
705  * csr_cert.issuer = ca_cert.subject
706  *
707  * extension_factory = OpenSSL::X509::ExtensionFactory.new
708  * extension_factory.subject_certificate = csr_cert
709  * extension_factory.issuer_certificate = ca_cert
710  *
711  * extension_factory.create_extension 'basicConstraints', 'CA:FALSE'
712  * extension_factory.create_extension 'keyUsage',
713  * 'keyEncipherment,dataEncipherment,digitalSignature'
714  * extension_factory.create_extension 'subjectKeyIdentifier', 'hash'
715  *
716  * csr_cert.sign ca_key, OpenSSL::Digest::SHA1.new
717  *
718  * open 'csr_cert.pem', 'w' do |io|
719  * io.write csr_cert.to_pem
720  * end
721  *
722  * == SSL and TLS Connections
723  *
724  * Using our created key and certificate we can create an SSL or TLS connection.
725  * An SSLContext is used to set up an SSL session.
726  *
727  * context = OpenSSL::SSL::SSLContext.new
728  *
729  * === SSL Server
730  *
731  * An SSL server requires the certificate and private key to communicate
732  * securely with its clients:
733  *
734  * context.cert = cert
735  * context.key = key
736  *
737  * Then create an SSLServer with a TCP server socket and the context. Use the
738  * SSLServer like an ordinary TCP server.
739  *
740  * require 'socket'
741  *
742  * tcp_server = TCPServer.new 5000
743  * ssl_server = OpenSSL::SSL::SSLServer.new tcp_server, context
744  *
745  * loop do
746  * ssl_connection = ssl_server.accept
747  *
748  * data = connection.gets
749  *
750  * response = "I got #{data.dump}"
751  * puts response
752  *
753  * connection.puts "I got #{data.dump}"
754  * connection.close
755  * end
756  *
757  * === SSL client
758  *
759  * An SSL client is created with a TCP socket and the context.
760  * SSLSocket#connect must be called to initiate the SSL handshake and start
761  * encryption. A key and certificate are not required for the client socket.
762  *
763  * require 'socket'
764  *
765  * tcp_client = TCPSocket.new 'localhost', 5000
766  * ssl_client = OpenSSL::SSL::SSLSocket.new client_socket, context
767  * ssl_client.connect
768  *
769  * ssl_client.puts "hello server!"
770  * puts ssl_client.gets
771  *
772  * === Peer Verification
773  *
774  * An unverified SSL connection does not provide much security. For enhanced
775  * security the client or server can verify the certificate of its peer.
776  *
777  * The client can be modified to verify the server's certificate against the
778  * certificate authority's certificate:
779  *
780  * context.ca_file = 'ca_cert.pem'
781  * context.verify_mode = OpenSSL::SSL::VERIFY_PEER
782  *
783  * require 'socket'
784  *
785  * tcp_client = TCPSocket.new 'localhost', 5000
786  * ssl_client = OpenSSL::SSL::SSLSocket.new client_socket, context
787  * ssl_client.connect
788  *
789  * ssl_client.puts "hello server!"
790  * puts ssl_client.gets
791  *
792  * If the server certificate is invalid or <tt>context.ca_file</tt> is not set
793  * when verifying peers an OpenSSL::SSL::SSLError will be raised.
794  *
795  */
796 void
798 {
799  /*
800  * Init timezone info
801  */
802 #if 0
803  tzset();
804 #endif
805 
806  /*
807  * Init all digests, ciphers
808  */
809  /* CRYPTO_malloc_init(); */
810  /* ENGINE_load_builtin_engines(); */
811  OpenSSL_add_ssl_algorithms();
812  OpenSSL_add_all_algorithms();
813  ERR_load_crypto_strings();
814  SSL_load_error_strings();
815 
816  /*
817  * FIXME:
818  * On unload do:
819  */
820 #if 0
821  CONF_modules_unload(1);
822  destroy_ui_method();
823  EVP_cleanup();
824  ENGINE_cleanup();
825  CRYPTO_cleanup_all_ex_data();
826  ERR_remove_state(0);
827  ERR_free_strings();
828 #endif
829 
830  /*
831  * Init main module
832  */
833  mOSSL = rb_define_module("OpenSSL");
834 
835  /*
836  * OpenSSL ruby extension version
837  */
838  rb_define_const(mOSSL, "VERSION", rb_str_new2(OSSL_VERSION));
839 
840  /*
841  * Version of OpenSSL the ruby OpenSSL extension was built with
842  */
843  rb_define_const(mOSSL, "OPENSSL_VERSION", rb_str_new2(OPENSSL_VERSION_TEXT));
844  /*
845  * Version number of OpenSSL the ruby OpenSSL extension was built with
846  * (base 16)
847  */
848  rb_define_const(mOSSL, "OPENSSL_VERSION_NUMBER", INT2NUM(OPENSSL_VERSION_NUMBER));
849 
850  /*
851  * Generic error,
852  * common for all classes under OpenSSL module
853  */
854  eOSSLError = rb_define_class_under(mOSSL,"OpenSSLError",rb_eStandardError);
855 
856  /*
857  * Verify callback Proc index for ext-data
858  */
859  if ((ossl_verify_cb_idx = X509_STORE_CTX_get_ex_new_index(0, (void *)"ossl_verify_cb_idx", 0, 0, 0)) < 0)
860  ossl_raise(eOSSLError, "X509_STORE_CTX_get_ex_new_index");
861 
862  /*
863  * Init debug core
864  */
865  dOSSL = Qfalse;
866  rb_define_module_function(mOSSL, "debug", ossl_debug_get, 0);
867  rb_define_module_function(mOSSL, "debug=", ossl_debug_set, 1);
868  rb_define_module_function(mOSSL, "errors", ossl_get_errors, 0);
869 
870  /*
871  * Get ID of to_der
872  */
873  ossl_s_to_der = rb_intern("to_der");
874 
875  /*
876  * Init components
877  */
878  Init_ossl_bn();
882  Init_ossl_hmac();
885  Init_ossl_pkcs7();
886  Init_ossl_pkcs5();
887  Init_ossl_pkey();
888  Init_ossl_rand();
889  Init_ossl_ssl();
890  Init_ossl_x509();
891  Init_ossl_ocsp();
893  Init_ossl_asn1();
894 }
895 
896 #if defined(OSSL_DEBUG)
897 /*
898  * Check if all symbols are OK with 'make LDSHARED=gcc all'
899  */
900 int
901 main(int argc, char *argv[])
902 {
903  return 0;
904 }
905 #endif /* OSSL_DEBUG */
906 
#define RSTRING_LEN(string)
Definition: generator.h:45
VALUE rb_eStandardError
Definition: error.c:465
VALUE mOSSL
Definition: ossl.c:250
volatile VALUE ary
Definition: tcltklib.c:9700
static VALUE ossl_str_new(int size)
Definition: ossl.c:128
VALUE dOSSL
Definition: ossl.c:370
ID ossl_s_to_der
Definition: ossl.c:260
parser parser_yylval val
Definition: ripper.c:14289
void Init_ossl_config()
Definition: ossl_config.c:63
VALUE proc
Definition: tcltklib.c:2948
int ret
Definition: tcltklib.c:276
int status
Definition: tcltklib.c:2186
unsigned long VALUE
Definition: ruby.h:88
VALUE exc
Definition: tcltklib.c:3085
VALUE rb_ary_push(VALUE ary, VALUE item)
Definition: array.c:740
void Init_ossl_bn()
Definition: ossl_bn.c:734
static VALUE INT2NUM(int v)
Definition: ruby.h:981
#define OSSL_IMPL_SK2ARY(name, type)
Definition: ossl.c:98
VALUE rb_protect(VALUE(*proc)(VALUE), VALUE data, int *state)
Definition: eval.c:704
#define RSTRING_PTR(string)
Definition: generator.h:42
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
Definition: class.c:515
return Qtrue
Definition: tcltklib.c:9597
#define OSSL_VERSION
Definition: ossl_version.h:14
void * X509_STORE_get_ex_data(X509_STORE *str, int idx)
void Init_ossl_pkcs5()
Definition: ossl_pkcs5.c:90
void Init_ossl_pkey()
Definition: ossl_pkey.c:304
static VALUE ossl_make_error(VALUE exc, const char *fmt, va_list args)
Definition: ossl.c:285
return str
Definition: ruby.c:1183
void Init_ossl_pkcs12()
Definition: ossl_pkcs12.c:195
int ossl_verify_cb_idx
Definition: ossl.c:197
VALUE ossl_get_errors()
Definition: ossl.c:354
VALUE VALUE args
Definition: tcltklib.c:2550
flag
Definition: tcltklib.c:2039
void ossl_debug(const char *fmt,...)
Definition: ossl.c:374
const char * fmt
Definition: tcltklib.c:837
void Init_ossl_pkcs7()
Definition: ossl_pkcs7.c:981
void Init_ossl_hmac()
Definition: ossl_hmac.c:237
VALUE ossl_exc_new(VALUE exc, const char *fmt,...)
Definition: ossl.c:335
void Init_openssl()
Definition: ossl.c:797
void rb_exc_raise(VALUE mesg)
Definition: eval.c:460
static VALUE ossl_pem_passwd_cb0(VALUE flag)
Definition: ossl.c:151
#define Qnil
Definition: ruby.h:367
n NULL
Definition: yaml2byte.c:134
VALUE ossl_x509stctx_clear_ptr(VALUE)
VALUE ossl_to_der_if_possible(VALUE obj)
Definition: ossl.c:274
VALUE store_ctx
Definition: ossl.h:167
return Qfalse
Definition: tcltklib.c:6768
int rb_block_given_p(void)
Definition: eval.c:604
VALUE preverify_ok
Definition: ossl.h:166
VALUE cX509Cert
Definition: ossl_x509cert.c:33
void Init_ossl_ssl()
Definition: ossl_ssl.c:1685
void Init_ossl_ocsp()
Definition: ossl_ocsp.c:783
VALUE ossl_x509stctx_new(X509_STORE_CTX *)
void Init_ossl_asn1()
Definition: ossl_asn1.c:1444
VALUE rb_str_cat2(VALUE, const char *)
Definition: string.c:1908
VALUE rb_ary_new(void)
Definition: array.c:339
va_end(args)
#define NIL_P(v)
Definition: ruby.h:374
static VALUE VALUE obj
Definition: tcltklib.c:3147
void rb_define_const(VALUE, const char *, VALUE)
Definition: variable.c:1923
VALUE eOSSLError
Definition: ossl.c:255
void Init_ossl_rand()
Definition: ossl_rand.c:182
unsigned char buf[MIME_BUF_SIZE]
Definition: nkf.c:3913
int err
Definition: win32.c:78
void Init_ossl_engine()
Definition: ossl_engine.c:405
int PEM_def_callback(char *buf, int num, int w, void *key)
VALUE * argv
Definition: tcltklib.c:1962
static VALUE ossl_debug_get(VALUE self)
Definition: ossl.c:393
memcpy(buf+1, str, len)
void rb_define_module_function(VALUE module, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a module function for module.
Definition: class.c:1358
VALUE rb_yield(VALUE)
Definition: vm_eval.c:781
unsigned long ID
Definition: ruby.h:89
int argc
Definition: tcltklib.c:1961
#define OSSL_IMPL_ARY2SK(name, type, expected_class, dup)
Definition: ossl.c:50
register unsigned int len
Definition: name2ctype.h:22210
VALUE rb_str_new_cstr(const char *)
Definition: string.c:432
void rb_jump_tag(int tag)
Definition: eval.c:598
static VALUE ossl_debug_set(VALUE self, VALUE val)
Definition: ossl.c:406
#define _(args)
Definition: dln.h:28
state
Definition: gb18030.c:213
VALUE msg
Definition: tcltklib.c:842
int rb_respond_to(VALUE, ID)
Definition: vm_method.c:1231
void Init_ossl_digest()
Definition: ossl_digest.c:297
int size
Definition: encoding.c:51
VALUE rb_exc_new3(VALUE etype, VALUE str)
Definition: error.c:504
VALUE ossl_buf2str(char *buf, int len)
Definition: ossl.c:134
void ossl_raise(VALUE exc, const char *fmt,...)
Definition: ossl.c:324
void Init_ossl_ns_spki()
Definition: ossl_ns_spki.c:235
#define SafeStringValue(v)
Definition: ruby.h:472
X509 * DupX509CertPtr(VALUE)
int main(int argc, char **argv)
Definition: nkf.c:6446
return rb_funcall(q->proc, ID_call, 0)
void Init_ossl_cipher(void)
Definition: ossl_cipher.c:568
BDIGIT e
Definition: bigdecimal.c:4946
int ossl_pem_passwd_cb(char *buf, int max_len, int flag, void *pwd)
Definition: ossl.c:162
void rb_warning(const char *fmt,...)
Definition: error.c:212
#define RSTRING_LENINT(str)
Definition: ruby.h:684
VALUE ossl_call_verify_cb_proc(struct ossl_verify_cb_args *args)
Definition: ossl.c:200
ssize_t i
Definition: bigdecimal.c:5519
VALUE rb_define_module(const char *name)
Definition: class.c:587
#define rb_intern(str)
void Init_ossl_x509()
Definition: ossl_x509.c:20
VALUE rb_vsprintf(const char *, va_list)
Definition: sprintf.c:1197
VALUE rb_str_new2(const char *)
void rb_warn(const char *fmt,...)
Definition: error.c:196
int string2hex(const unsigned char *buf, int buf_len, char **hexbuf, int *hexbuf_len)
Definition: ossl.c:18
int ossl_verify_cb(int ok, X509_STORE_CTX *ctx)
Definition: ossl.c:207
VALUE ossl_to_der(VALUE obj)
Definition: ossl.c:263
#define StringValue(v)
Definition: ruby.h:466
VALUE rb_str_new(const char *, long)
Definition: string.c:410