Ruby 2.0.0p353(2013-11-22revision43784)

- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

ossl_engine.c
Go to the documentation of this file.
1 /*
2 * $Id: ossl_engine.c 33634 2011-11-04 07:19:23Z nobu $
3 * 'OpenSSL for Ruby' project
4 * Copyright (C) 2003 GOTOU Yuuzou <gotoyuzo@notwork.org>
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
13 #if defined(OSSL_ENGINE_ENABLED)
14
15 #define WrapEngine(klass, obj, engine) do { \
16 if (!(engine)) { \
17 ossl_raise(rb_eRuntimeError, "ENGINE wasn't initialized."); \
18 } \
19 (obj) = Data_Wrap_Struct((klass), 0, ENGINE_free, (engine)); \
20 } while(0)
21 #define GetEngine(obj, engine) do { \
22 Data_Get_Struct((obj), ENGINE, (engine)); \
23 if (!(engine)) { \
24 ossl_raise(rb_eRuntimeError, "ENGINE wasn't initialized."); \
25 } \
26 } while (0)
27 #define SafeGetEngine(obj, engine) do { \
28 OSSL_Check_Kind((obj), cEngine); \
29 GetPKCS7((obj), (engine)); \
30 } while (0)
31
32 /*
33 * Classes
34 */
35 VALUE cEngine;
36 VALUE eEngineError;
37
38 /*
39 * Private
40 */
41 #define OSSL_ENGINE_LOAD_IF_MATCH(x) \
42 do{\
43 if(!strcmp(#x, RSTRING_PTR(name))){\
44 ENGINE_load_##x();\
45 return Qtrue;\
46 }\
47 }while(0)
48
49 static VALUE
50 ossl_engine_s_load(int argc, VALUE *argv, VALUE klass)
51 {
52 #if !defined(HAVE_ENGINE_LOAD_BUILTIN_ENGINES)
53 return Qnil;
54 #else
55 VALUE name;
56
57 rb_scan_args(argc, argv, "01", &name);
58 if(NIL_P(name)){
59 ENGINE_load_builtin_engines();
60 return Qtrue;
61 }
62 StringValue(name);
63 #ifndef OPENSSL_NO_STATIC_ENGINE
64 #if HAVE_ENGINE_LOAD_DYNAMIC
65 OSSL_ENGINE_LOAD_IF_MATCH(dynamic);
66 #endif
67 #if HAVE_ENGINE_LOAD_4758CCA
68 OSSL_ENGINE_LOAD_IF_MATCH(4758cca);
69 #endif
70 #if HAVE_ENGINE_LOAD_AEP
71 OSSL_ENGINE_LOAD_IF_MATCH(aep);
72 #endif
73 #if HAVE_ENGINE_LOAD_ATALLA
74 OSSL_ENGINE_LOAD_IF_MATCH(atalla);
75 #endif
76 #if HAVE_ENGINE_LOAD_CHIL
77 OSSL_ENGINE_LOAD_IF_MATCH(chil);
78 #endif
79 #if HAVE_ENGINE_LOAD_CSWIFT
80 OSSL_ENGINE_LOAD_IF_MATCH(cswift);
81 #endif
82 #if HAVE_ENGINE_LOAD_NURON
83 OSSL_ENGINE_LOAD_IF_MATCH(nuron);
84 #endif
85 #if HAVE_ENGINE_LOAD_SUREWARE
86 OSSL_ENGINE_LOAD_IF_MATCH(sureware);
87 #endif
88 #if HAVE_ENGINE_LOAD_UBSEC
89 OSSL_ENGINE_LOAD_IF_MATCH(ubsec);
90 #endif
91 #if HAVE_ENGINE_LOAD_PADLOCK
92 OSSL_ENGINE_LOAD_IF_MATCH(padlock);
93 #endif
94 #if HAVE_ENGINE_LOAD_CAPI
95 OSSL_ENGINE_LOAD_IF_MATCH(capi);
96 #endif
97 #if HAVE_ENGINE_LOAD_GMP
98 OSSL_ENGINE_LOAD_IF_MATCH(gmp);
99 #endif
100 #if HAVE_ENGINE_LOAD_GOST
101 OSSL_ENGINE_LOAD_IF_MATCH(gost);
102 #endif
103 #if HAVE_ENGINE_LOAD_CRYPTODEV
104 OSSL_ENGINE_LOAD_IF_MATCH(cryptodev);
105 #endif
106 #if HAVE_ENGINE_LOAD_AESNI
107 OSSL_ENGINE_LOAD_IF_MATCH(aesni);
108 #endif
109 #endif
110 #ifdef HAVE_ENGINE_LOAD_OPENBSD_DEV_CRYPTO
111 OSSL_ENGINE_LOAD_IF_MATCH(openbsd_dev_crypto);
112 #endif
113 OSSL_ENGINE_LOAD_IF_MATCH(openssl);
114 rb_warning("no such builtin loader for `%s'", RSTRING_PTR(name));
115 return Qnil;
116 #endif /* HAVE_ENGINE_LOAD_BUILTIN_ENGINES */
117 }
118
119 static VALUE
120 ossl_engine_s_cleanup(VALUE self)
121 {
122 #if defined(HAVE_ENGINE_CLEANUP)
123 ENGINE_cleanup();
124 #endif
125 return Qnil;
126 }
127
128 static VALUE
129 ossl_engine_s_engines(VALUE klass)
130 {
131 ENGINE *e;
132 VALUE ary, obj;
133
134 ary = rb_ary_new();
135 for(e = ENGINE_get_first(); e; e = ENGINE_get_next(e)){
136 /* Need a ref count of two here because of ENGINE_free being
137 * called internally by OpenSSL when moving to the next ENGINE
138 * and by us when releasing the ENGINE reference */
139 ENGINE_up_ref(e);
140 WrapEngine(klass, obj, e);
141 rb_ary_push(ary, obj);
142 }
143
144 return ary;
145 }
146
147 static VALUE
148 ossl_engine_s_by_id(VALUE klass, VALUE id)
149 {
150 ENGINE *e;
151 VALUE obj;
152
153 StringValue(id);
154 ossl_engine_s_load(1, &id, klass);
155 if(!(e = ENGINE_by_id(RSTRING_PTR(id))))
156 ossl_raise(eEngineError, NULL);
157 WrapEngine(klass, obj, e);
158 if(rb_block_given_p()) rb_yield(obj);
159 if(!ENGINE_init(e))
160 ossl_raise(eEngineError, NULL);
161 ENGINE_ctrl(e, ENGINE_CTRL_SET_PASSWORD_CALLBACK,
162 0, NULL, (void(*)(void))ossl_pem_passwd_cb);
163 ERR_clear_error();
164
165 return obj;
166 }
167
168 static VALUE
169 ossl_engine_s_alloc(VALUE klass)
170 {
171 ENGINE *e;
172 VALUE obj;
173
174 if (!(e = ENGINE_new())) {
175 ossl_raise(eEngineError, NULL);
176 }
177 WrapEngine(klass, obj, e);
178
179 return obj;
180 }
181
182 static VALUE
183 ossl_engine_get_id(VALUE self)
184 {
185 ENGINE *e;
186 GetEngine(self, e);
187 return rb_str_new2(ENGINE_get_id(e));
188 }
189
190 static VALUE
191 ossl_engine_get_name(VALUE self)
192 {
193 ENGINE *e;
194 GetEngine(self, e);
195 return rb_str_new2(ENGINE_get_name(e));
196 }
197
198 static VALUE
199 ossl_engine_finish(VALUE self)
200 {
201 ENGINE *e;
202
203 GetEngine(self, e);
204 if(!ENGINE_finish(e)) ossl_raise(eEngineError, NULL);
205
206 return Qnil;
207 }
208
209 #if defined(HAVE_ENGINE_GET_CIPHER)
210 static VALUE
211 ossl_engine_get_cipher(VALUE self, VALUE name)
212 {
213 ENGINE *e;
214 const EVP_CIPHER *ciph, *tmp;
215 char *s;
216 int nid;
217
218 s = StringValuePtr(name);
219 tmp = EVP_get_cipherbyname(s);
220 if(!tmp) ossl_raise(eEngineError, "no such cipher `%s'", s);
221 nid = EVP_CIPHER_nid(tmp);
222 GetEngine(self, e);
223 ciph = ENGINE_get_cipher(e, nid);
224 if(!ciph) ossl_raise(eEngineError, NULL);
225
226 return ossl_cipher_new(ciph);
227 }
228 #else
229 #define ossl_engine_get_cipher rb_f_notimplement
230 #endif
231
232 #if defined(HAVE_ENGINE_GET_DIGEST)
233 static VALUE
234 ossl_engine_get_digest(VALUE self, VALUE name)
235 {
236 ENGINE *e;
237 const EVP_MD *md, *tmp;
238 char *s;
239 int nid;
240
241 s = StringValuePtr(name);
242 tmp = EVP_get_digestbyname(s);
243 if(!tmp) ossl_raise(eEngineError, "no such digest `%s'", s);
244 nid = EVP_MD_nid(tmp);
245 GetEngine(self, e);
246 md = ENGINE_get_digest(e, nid);
247 if(!md) ossl_raise(eEngineError, NULL);
248
249 return ossl_digest_new(md);
250 }
251 #else
252 #define ossl_engine_get_digest rb_f_notimplement
253 #endif
254
255 static VALUE
256 ossl_engine_load_privkey(int argc, VALUE *argv, VALUE self)
257 {
258 ENGINE *e;
259 EVP_PKEY *pkey;
260 VALUE id, data, obj;
261 char *sid, *sdata;
262
263 rb_scan_args(argc, argv, "02", &id, &data);
264 sid = NIL_P(id) ? NULL : StringValuePtr(id);
265 sdata = NIL_P(data) ? NULL : StringValuePtr(data);
266 GetEngine(self, e);
267 #if OPENSSL_VERSION_NUMBER < 0x00907000L
268 pkey = ENGINE_load_private_key(e, sid, sdata);
269 #else
270 pkey = ENGINE_load_private_key(e, sid, NULL, sdata);
271 #endif
272 if (!pkey) ossl_raise(eEngineError, NULL);
273 obj = ossl_pkey_new(pkey);
274 OSSL_PKEY_SET_PRIVATE(obj);
275
276 return obj;
277 }
278
279 static VALUE
280 ossl_engine_load_pubkey(int argc, VALUE *argv, VALUE self)
281 {
282 ENGINE *e;
283 EVP_PKEY *pkey;
284 VALUE id, data;
285 char *sid, *sdata;
286
287 rb_scan_args(argc, argv, "02", &id, &data);
288 sid = NIL_P(id) ? NULL : StringValuePtr(id);
289 sdata = NIL_P(data) ? NULL : StringValuePtr(data);
290 GetEngine(self, e);
291 #if OPENSSL_VERSION_NUMBER < 0x00907000L
292 pkey = ENGINE_load_public_key(e, sid, sdata);
293 #else
294 pkey = ENGINE_load_public_key(e, sid, NULL, sdata);
295 #endif
296 if (!pkey) ossl_raise(eEngineError, NULL);
297
298 return ossl_pkey_new(pkey);
299 }
300
301 static VALUE
302 ossl_engine_set_default(VALUE self, VALUE flag)
303 {
304 ENGINE *e;
305 int f = NUM2INT(flag);
306
307 GetEngine(self, e);
308 ENGINE_set_default(e, f);
309
310 return Qtrue;
311 }
312
313 static VALUE
314 ossl_engine_ctrl_cmd(int argc, VALUE *argv, VALUE self)
315 {
316 ENGINE *e;
317 VALUE cmd, val;
318 int ret;
319
320 GetEngine(self, e);
321 rb_scan_args(argc, argv, "11", &cmd, &val);
322 StringValue(cmd);
323 if (!NIL_P(val)) StringValue(val);
324 ret = ENGINE_ctrl_cmd_string(e, RSTRING_PTR(cmd),
325 NIL_P(val) ? NULL : RSTRING_PTR(val), 0);
326 if (!ret) ossl_raise(eEngineError, NULL);
327
328 return self;
329 }
330
331 static VALUE
332 ossl_engine_cmd_flag_to_name(int flag)
333 {
334 switch(flag){
335 case ENGINE_CMD_FLAG_NUMERIC: return rb_str_new2("NUMERIC");
336 case ENGINE_CMD_FLAG_STRING: return rb_str_new2("STRING");
337 case ENGINE_CMD_FLAG_NO_INPUT: return rb_str_new2("NO_INPUT");
338 case ENGINE_CMD_FLAG_INTERNAL: return rb_str_new2("INTERNAL");
339 default: return rb_str_new2("UNKNOWN");
340 }
341 }
342
343 static VALUE
344 ossl_engine_get_cmds(VALUE self)
345 {
346 ENGINE *e;
347 const ENGINE_CMD_DEFN *defn, *p;
348 VALUE ary, tmp;
349
350 GetEngine(self, e);
351 ary = rb_ary_new();
352 if ((defn = ENGINE_get_cmd_defns(e)) != NULL){
353 for (p = defn; p->cmd_num > 0; p++){
354 tmp = rb_ary_new();
355 rb_ary_push(tmp, rb_str_new2(p->cmd_name));
356 rb_ary_push(tmp, rb_str_new2(p->cmd_desc));
357 rb_ary_push(tmp, ossl_engine_cmd_flag_to_name(p->cmd_flags));
358 rb_ary_push(ary, tmp);
359 }
360 }
361
362 return ary;
363 }
364
365 static VALUE
366 ossl_engine_inspect(VALUE self)
367 {
368 VALUE str;
369 const char *cname = rb_class2name(rb_obj_class(self));
370
371 str = rb_str_new2("#<");
372 rb_str_cat2(str, cname);
373 rb_str_cat2(str, " id=\"");
374 rb_str_append(str, ossl_engine_get_id(self));
375 rb_str_cat2(str, "\" name=\"");
376 rb_str_append(str, ossl_engine_get_name(self));
377 rb_str_cat2(str, "\">");
378
379 return str;
380 }
381
382 #define DefEngineConst(x) rb_define_const(cEngine, #x, INT2NUM(ENGINE_##x))
383
384 void
385 Init_ossl_engine()
386 {
387 cEngine = rb_define_class_under(mOSSL, "Engine", rb_cObject);
388 eEngineError = rb_define_class_under(cEngine, "EngineError", eOSSLError);
389
390 rb_define_alloc_func(cEngine, ossl_engine_s_alloc);
391 rb_define_singleton_method(cEngine, "load", ossl_engine_s_load, -1);
392 rb_define_singleton_method(cEngine, "cleanup", ossl_engine_s_cleanup, 0);
393 rb_define_singleton_method(cEngine, "engines", ossl_engine_s_engines, 0);
394 rb_define_singleton_method(cEngine, "by_id", ossl_engine_s_by_id, 1);
395 rb_undef_method(CLASS_OF(cEngine), "new");
396
397 rb_define_method(cEngine, "id", ossl_engine_get_id, 0);
398 rb_define_method(cEngine, "name", ossl_engine_get_name, 0);
399 rb_define_method(cEngine, "finish", ossl_engine_finish, 0);
400 rb_define_method(cEngine, "cipher", ossl_engine_get_cipher, 1);
401 rb_define_method(cEngine, "digest", ossl_engine_get_digest, 1);
402 rb_define_method(cEngine, "load_private_key", ossl_engine_load_privkey, -1);
403 rb_define_method(cEngine, "load_public_key", ossl_engine_load_pubkey, -1);
404 rb_define_method(cEngine, "set_default", ossl_engine_set_default, 1);
405 rb_define_method(cEngine, "ctrl_cmd", ossl_engine_ctrl_cmd, -1);
406 rb_define_method(cEngine, "cmds", ossl_engine_get_cmds, 0);
407 rb_define_method(cEngine, "inspect", ossl_engine_inspect, 0);
408
409 DefEngineConst(METHOD_RSA);
410 DefEngineConst(METHOD_DSA);
411 DefEngineConst(METHOD_DH);
412 DefEngineConst(METHOD_RAND);
413 #ifdef ENGINE_METHOD_BN_MOD_EXP
414 DefEngineConst(METHOD_BN_MOD_EXP);
415 #endif
416 #ifdef ENGINE_METHOD_BN_MOD_EXP_CRT
417 DefEngineConst(METHOD_BN_MOD_EXP_CRT);
418 #endif
419 #ifdef ENGINE_METHOD_CIPHERS
420 DefEngineConst(METHOD_CIPHERS);
421 #endif
422 #ifdef ENGINE_METHOD_DIGESTS
423 DefEngineConst(METHOD_DIGESTS);
424 #endif
425 DefEngineConst(METHOD_ALL);
426 DefEngineConst(METHOD_NONE);
427 }
428 #else
429 void
430 Init_ossl_engine()
431 {
432 }
433 #endif
data
VALUE data
Definition: tcltklib.c:3368
tmp
volatile VALUE tmp
Definition: tcltklib.c:10209
mOSSL
VALUE mOSSL
Definition: ossl.c:259
ary
volatile VALUE ary
Definition: tcltklib.c:9713
p
Win32OLEIDispatch * p
Definition: win32ole.c:786
rb_define_singleton_method
void rb_define_singleton_method(VALUE obj, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a singleton method for obj.
Definition: class.c:1497
ret
int ret
Definition: tcltklib.c:280
rb_define_alloc_func
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
eEngineError
VALUE eEngineError
rb_ary_push
VALUE rb_ary_push(VALUE ary, VALUE item)
Definition: array.c:822
RSTRING_PTR
#define RSTRING_PTR(str)
CLASS_OF
#define CLASS_OF(v)
NIL_P
NIL_P(eventloop_thread)
Definition: tcltklib.c:4068
rb_define_class_under
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
Definition: class.c:545
Qtrue
return Qtrue
Definition: tcltklib.c:9610
rb_obj_class
VALUE rb_obj_class(VALUE)
Definition: object.c:194
rb_str_new2
#define rb_str_new2
ossl_pkey_new
VALUE ossl_pkey_new(EVP_PKEY *pkey)
Definition: ossl_pkey.c:76
rb_undef_method
void rb_undef_method(VALUE klass, const char *name)
Definition: class.c:1362
rb_str_append
VALUE rb_str_append(VALUE, VALUE)
Definition: string.c:2121
flag
flag
Definition: tcltklib.c:2048
cEngine
VALUE cEngine
ossl_cipher_new
VALUE ossl_cipher_new(const EVP_CIPHER *cipher)
Definition: ossl_cipher.c:55
OSSL_PKEY_SET_PRIVATE
#define OSSL_PKEY_SET_PRIVATE(obj)
Definition: ossl_pkey.h:19
rb_block_given_p
int rb_block_given_p(void)
Definition: eval.c:672
Qnil
#define Qnil
Definition: tcltklib.c:1896
StringValuePtr
#define StringValuePtr(v)
val
#define val
Definition: tcltklib.c:1949
str
static VALUE char * str
Definition: tcltklib.c:3547
rb_ary_new
VALUE rb_ary_new(void)
Definition: array.c:424
ossl_digest_new
VALUE ossl_digest_new(const EVP_MD *md)
Definition: ossl_digest.c:64
rb_str_cat2
VALUE rb_str_cat2(VALUE, const char *)
Definition: string.c:1982
obj
static VALUE VALUE obj
Definition: tcltklib.c:3158
eOSSLError
VALUE eOSSLError
Definition: ossl.c:264
Init_ossl_engine
void Init_ossl_engine()
Definition: ossl_engine.c:430
argv
VALUE * argv
Definition: tcltklib.c:1971
rb_yield
VALUE rb_yield(VALUE)
Definition: vm_eval.c:934
id
const int id
Definition: nkf.c:209
StringValue
#define StringValue(v)
s
register char * s
Definition: os2.c:56
rb_scan_args
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1570
argc
int argc
Definition: tcltklib.c:1970
cmd
const char * cmd
Definition: tcltklib.c:278
rb_class2name
const char * rb_class2name(VALUE)
Definition: variable.c:389
f
#define f
rb_cObject
RUBY_EXTERN VALUE rb_cObject
Definition: ripper.y:1426
klass
klass
Definition: tcltklib.c:3504
ossl_raise
void ossl_raise(VALUE exc, const char *fmt,...)
Definition: ossl.c:328
NUM2INT
#define NUM2INT(x)
ossl.h
e
BDIGIT e
Definition: bigdecimal.c:5085
VALUE
unsigned long VALUE
Definition: ripper.y:104
ossl_pem_passwd_cb
int ossl_pem_passwd_cb(char *buf, int max_len, int flag, void *pwd)
Definition: ossl.c:162
rb_warning
void rb_warning(const char *fmt,...)
Definition: error.c:229
NULL
#define NULL
Definition: _sdbm.c:103
name
const char * name
Definition: nkf.c:208
rb_define_method
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1344