Ruby  2.0.0p353(2013-11-22revision43784)
ossl_ssl_session.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2004-2007 Technorama Ltd. <oss-ruby@technorama.net>
3  */
4 
5 #include "ossl.h"
6 
7 #define GetSSLSession(obj, sess) do { \
8  Data_Get_Struct((obj), SSL_SESSION, (sess)); \
9  if (!(sess)) { \
10  ossl_raise(rb_eRuntimeError, "SSL Session wasn't initialized."); \
11  } \
12 } while (0)
13 
14 #define SafeGetSSLSession(obj, sess) do { \
15  OSSL_Check_Kind((obj), cSSLSession); \
16  GetSSLSession((obj), (sess)); \
17 } while (0)
18 
19 
22 
24 {
25  return Data_Wrap_Struct(klass, 0, SSL_SESSION_free, NULL);
26 }
27 
28 /*
29  * call-seq:
30  * Session.new(SSLSocket | string) => session
31  *
32  * === Parameters
33  * +SSLSocket+ is an OpenSSL::SSL::SSLSocket
34  * +string+ must be a DER or PEM encoded Session.
35 */
37 {
38  SSL_SESSION *ctx = NULL;
39 
40  if (RDATA(self)->data)
41  ossl_raise(eSSLSession, "SSL Session already initialized");
42 
43  if (rb_obj_is_instance_of(arg1, cSSLSocket)) {
44  SSL *ssl;
45 
46  Data_Get_Struct(arg1, SSL, ssl);
47 
48  if (!ssl || (ctx = SSL_get1_session(ssl)) == NULL)
49  ossl_raise(eSSLSession, "no session available");
50  } else {
51  BIO *in = ossl_obj2bio(arg1);
52 
53  ctx = PEM_read_bio_SSL_SESSION(in, NULL, NULL, NULL);
54 
55  if (!ctx) {
56  OSSL_BIO_reset(in);
57  ctx = d2i_SSL_SESSION_bio(in, NULL);
58  }
59 
60  BIO_free(in);
61 
62  if (!ctx)
63  ossl_raise(rb_eArgError, "unknown type");
64  }
65 
66  /* should not happen */
67  if (ctx == NULL)
68  ossl_raise(eSSLSession, "ctx not set - internal error");
69 
70  RDATA(self)->data = ctx;
71 
72  return self;
73 }
74 
75 #if HAVE_SSL_SESSION_CMP == 0
76 int SSL_SESSION_cmp(const SSL_SESSION *a,const SSL_SESSION *b)
77 {
78  if (a->ssl_version != b->ssl_version ||
79  a->session_id_length != b->session_id_length)
80  return 1;
81  return memcmp(a->session_id,b-> session_id, a->session_id_length);
82 }
83 #endif
84 
85 /*
86  * call-seq:
87  * session1 == session2 -> boolean
88  *
89 */
91 {
92  SSL_SESSION *ctx1, *ctx2;
93 
94  GetSSLSession(val1, ctx1);
95  SafeGetSSLSession(val2, ctx2);
96 
97  switch (SSL_SESSION_cmp(ctx1, ctx2)) {
98  case 0: return Qtrue;
99  default: return Qfalse;
100  }
101 }
102 
103 /*
104  * call-seq:
105  * session.time -> Time
106  *
107  * Gets start time of the session.
108  *
109 */
111 {
112  SSL_SESSION *ctx;
113  time_t t;
114 
115  GetSSLSession(self, ctx);
116 
117  t = SSL_SESSION_get_time(ctx);
118 
119  if (t == 0)
120  return Qnil;
121 
122  return rb_funcall(rb_cTime, rb_intern("at"), 1, TIMET2NUM(t));
123 }
124 
125 /*
126  * call-seq:
127  * session.timeout -> integer
128  *
129  * Gets how long until the session expires in seconds.
130  *
131 */
133 {
134  SSL_SESSION *ctx;
135  time_t t;
136 
137  GetSSLSession(self, ctx);
138 
139  t = SSL_SESSION_get_timeout(ctx);
140 
141  return TIMET2NUM(t);
142 }
143 
144 /*
145  * call-seq:
146  * session.time=(Time) -> Time
147  * session.time=(integer) -> Time
148  *
149  * Sets start time of the session. Time resolution is in seconds.
150  *
151 */
153 {
154  SSL_SESSION *ctx;
155  long t;
156 
157  GetSSLSession(self, ctx);
158  if (rb_obj_is_instance_of(time_v, rb_cTime)) {
159  time_v = rb_funcall(time_v, rb_intern("to_i"), 0);
160  }
161  t = NUM2LONG(time_v);
162  SSL_SESSION_set_time(ctx, t);
163  return ossl_ssl_session_get_time(self);
164 }
165 
166 /*
167  * call-seq:
168  * session.timeout=(integer) -> integer
169  *
170  * Sets how long until the session expires in seconds.
171  *
172 */
174 {
175  SSL_SESSION *ctx;
176  long t;
177 
178  GetSSLSession(self, ctx);
179  t = NUM2LONG(time_v);
180  SSL_SESSION_set_timeout(ctx, t);
181  return ossl_ssl_session_get_timeout(self);
182 }
183 
184 #ifdef HAVE_SSL_SESSION_GET_ID
185 /*
186  * call-seq:
187  * session.id -> aString
188  *
189  * Returns the Session ID.
190 */
191 static VALUE ossl_ssl_session_get_id(VALUE self)
192 {
193  SSL_SESSION *ctx;
194  const unsigned char *p = NULL;
195  unsigned int i = 0;
196 
197  GetSSLSession(self, ctx);
198 
199  p = SSL_SESSION_get_id(ctx, &i);
200 
201  return rb_str_new((const char *) p, i);
202 }
203 #endif
204 
205 /*
206  * call-seq:
207  * session.to_der -> aString
208  *
209  * Returns an ASN1 encoded String that contains the Session object.
210 */
212 {
213  SSL_SESSION *ctx;
214  unsigned char *p;
215  int len;
216  VALUE str;
217 
218  GetSSLSession(self, ctx);
219  len = i2d_SSL_SESSION(ctx, NULL);
220  if (len <= 0) {
221  ossl_raise(eSSLSession, "i2d_SSL_SESSION");
222  }
223 
224  str = rb_str_new(0, len);
225  p = (unsigned char *)RSTRING_PTR(str);
226  i2d_SSL_SESSION(ctx, &p);
227  ossl_str_adjust(str, p);
228  return str;
229 }
230 
231 /*
232  * call-seq:
233  * session.to_pem -> String
234  *
235  * Returns a PEM encoded String that contains the Session object.
236 */
238 {
239  SSL_SESSION *ctx;
240  BIO *out;
241  BUF_MEM *buf;
242  VALUE str;
243  int i;
244 
245  GetSSLSession(self, ctx);
246 
247  if (!(out = BIO_new(BIO_s_mem()))) {
248  ossl_raise(eSSLSession, "BIO_s_mem()");
249  }
250 
251  if (!(i=PEM_write_bio_SSL_SESSION(out, ctx))) {
252  BIO_free(out);
253  ossl_raise(eSSLSession, "SSL_SESSION_print()");
254  }
255 
256  BIO_get_mem_ptr(out, &buf);
257  str = rb_str_new(buf->data, buf->length);
258  BIO_free(out);
259 
260  return str;
261 }
262 
263 
264 /*
265  * call-seq:
266  * session.to_text -> String
267  *
268  * Shows everything in the Session object.
269 */
271 {
272  SSL_SESSION *ctx;
273  BIO *out;
274  BUF_MEM *buf;
275  VALUE str;
276 
277  GetSSLSession(self, ctx);
278 
279  if (!(out = BIO_new(BIO_s_mem()))) {
280  ossl_raise(eSSLSession, "BIO_s_mem()");
281  }
282 
283  if (!SSL_SESSION_print(out, ctx)) {
284  BIO_free(out);
285  ossl_raise(eSSLSession, "SSL_SESSION_print()");
286  }
287 
288  BIO_get_mem_ptr(out, &buf);
289  str = rb_str_new(buf->data, buf->length);
290  BIO_free(out);
291 
292  return str;
293 }
294 
295 
297 {
298 #if 0
299  mOSSL = rb_define_module("OpenSSL"); /* let rdoc know about mOSSL */
301 #endif
304 
307 
309 
314 
315 #ifdef HAVE_SSL_SESSION_GET_ID
316  rb_define_method(cSSLSession, "id", ossl_ssl_session_get_id, 0);
317 #else
319 #endif
323 }
VALUE mOSSL
Definition: ossl.c:259
static VALUE ossl_ssl_session_initialize(VALUE self, VALUE arg1)
int i
Definition: win32ole.c:784
static VALUE ossl_ssl_session_to_text(VALUE self)
#define Data_Get_Struct(obj, type, sval)
Definition: ruby.h:1025
static VALUE ossl_ssl_session_get_timeout(VALUE self)
#define SafeGetSSLSession(obj, sess)
#define Qtrue
Definition: ruby.h:434
#define ossl_str_adjust(str, p)
Definition: ossl.h:138
#define GetSSLSession(obj, sess)
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
Definition: vm_eval.c:774
static VALUE ossl_ssl_session_set_time(VALUE self, VALUE time_v)
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
Definition: class.c:545
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
static VALUE ossl_ssl_session_alloc(VALUE klass)
#define RDATA(obj)
Definition: ruby.h:1103
void rb_undef_method(VALUE klass, const char *name)
Definition: class.c:1362
#define Data_Wrap_Struct(klass, mark, free, sval)
Definition: ruby.h:1007
Win32OLEIDispatch * p
Definition: win32ole.c:786
int SSL_SESSION_cmp(const SSL_SESSION *a, const SSL_SESSION *b)
VALUE mSSL
Definition: ossl_ssl.c:27
void Init_ossl_ssl_session(void)
RUBY_EXTERN VALUE rb_cObject
Definition: ruby.h:1426
VALUE cSSLSession
#define OSSL_BIO_reset(bio)
Definition: ossl.h:155
VALUE eOSSLError
Definition: ossl.c:264
#define Qfalse
Definition: ruby.h:433
static VALUE ossl_ssl_session_get_time(VALUE self)
BIO * ossl_obj2bio(VALUE obj)
Definition: ossl_bio.c:17
VALUE cSSLSocket
Definition: ossl_ssl.c:30
unsigned char buf[MIME_BUF_SIZE]
Definition: nkf.c:4308
#define Qnil
Definition: ruby.h:435
unsigned long VALUE
Definition: ruby.h:104
int memcmp(const void *s1, const void *s2, size_t len)
Definition: memcmp.c:7
static VALUE ossl_ssl_session_set_timeout(VALUE self, VALUE time_v)
VALUE rb_define_module_under(VALUE outer, const char *name)
Definition: class.c:637
#define RSTRING_PTR(str)
Definition: ruby.h:866
VALUE rb_obj_is_instance_of(VALUE, VALUE)
Definition: object.c:545
static VALUE ossl_ssl_session_eq(VALUE val1, VALUE val2)
void ossl_raise(VALUE exc, const char *fmt,...)
Definition: ossl.c:328
static VALUE eSSLSession
VALUE rb_define_module(const char *name)
Definition: class.c:617
#define rb_intern(str)
#define NULL
Definition: _sdbm.c:103
RUBY_EXTERN VALUE rb_cTime
Definition: ruby.h:1460
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1344
static VALUE ossl_ssl_session_to_pem(VALUE self)
static VALUE ossl_ssl_session_to_der(VALUE self)
VALUE rb_eArgError
Definition: error.c:512
#define NUM2LONG(x)
Definition: ruby.h:592
VALUE rb_str_new(const char *, long)
Definition: string.c:425