~ubuntu-branches/ubuntu/hardy/ruby1.8/hardy-updates

« back to all changes in this revision

Viewing changes to ext/openssl/ossl_engine.c

  • Committer: Bazaar Package Importer
  • Author(s): akira yamada
  • Date: 2007-03-13 22:11:58 UTC
  • mfrom: (1.1.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20070313221158-h3oql37brlaf2go2
Tags: 1.8.6-1
* new upstream version, 1.8.6.
* libruby1.8 conflicts with libopenssl-ruby1.8 (< 1.8.6) (closes: #410018)
* changed packaging style to cdbs from dbs.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * $Id: ossl_engine.c 11708 2007-02-12 23:01:19Z shyouhei $
 
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(name)->ptr)){\
 
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
    OSSL_ENGINE_LOAD_IF_MATCH(dynamic);
 
65
    OSSL_ENGINE_LOAD_IF_MATCH(cswift);
 
66
    OSSL_ENGINE_LOAD_IF_MATCH(chil);
 
67
    OSSL_ENGINE_LOAD_IF_MATCH(atalla);
 
68
    OSSL_ENGINE_LOAD_IF_MATCH(nuron);
 
69
    OSSL_ENGINE_LOAD_IF_MATCH(ubsec);
 
70
    OSSL_ENGINE_LOAD_IF_MATCH(aep);
 
71
    OSSL_ENGINE_LOAD_IF_MATCH(sureware);
 
72
    OSSL_ENGINE_LOAD_IF_MATCH(4758cca);
 
73
#endif
 
74
#ifdef HAVE_ENGINE_LOAD_OPENBSD_DEV_CRYPTO
 
75
    OSSL_ENGINE_LOAD_IF_MATCH(openbsd_dev_crypto);
 
76
#endif
 
77
    OSSL_ENGINE_LOAD_IF_MATCH(openssl);
 
78
    rb_warning("no such builtin loader for `%s'", RSTRING(name)->ptr);
 
79
    return Qnil;
 
80
#endif /* HAVE_ENGINE_LOAD_BUILTIN_ENGINES */
 
81
}
 
82
 
 
83
static VALUE
 
84
ossl_engine_s_cleanup(VALUE self)
 
85
{
 
86
#if defined(HAVE_ENGINE_CLEANUP)
 
87
    ENGINE_cleanup();
 
88
#endif
 
89
    return Qnil;
 
90
}
 
91
 
 
92
static VALUE
 
93
ossl_engine_s_engines(VALUE klass)
 
94
{
 
95
    ENGINE *e;
 
96
    VALUE ary, obj;
 
97
 
 
98
    ary = rb_ary_new();
 
99
    for(e = ENGINE_get_first(); e; e = ENGINE_get_next(e)){
 
100
        WrapEngine(klass, obj, e);
 
101
        rb_ary_push(ary, obj);
 
102
    }
 
103
 
 
104
    return ary;
 
105
}
 
106
 
 
107
static VALUE
 
108
ossl_engine_s_by_id(VALUE klass, VALUE id)
 
109
{
 
110
    ENGINE *e;
 
111
    VALUE obj;
 
112
 
 
113
    StringValue(id);
 
114
    ossl_engine_s_load(1, &id, klass);
 
115
    if(!(e = ENGINE_by_id(RSTRING(id)->ptr)))
 
116
        ossl_raise(eEngineError, NULL);
 
117
    WrapEngine(klass, obj, e);
 
118
    if(rb_block_given_p()) rb_yield(obj);
 
119
    if(!ENGINE_init(e))
 
120
        ossl_raise(eEngineError, NULL);
 
121
    ENGINE_ctrl(e, ENGINE_CTRL_SET_PASSWORD_CALLBACK,
 
122
                0, NULL, (void(*)())ossl_pem_passwd_cb);
 
123
    ERR_clear_error();
 
124
 
 
125
    return obj;
 
126
}
 
127
 
 
128
static VALUE
 
129
ossl_engine_s_alloc(VALUE klass)
 
130
{
 
131
    ENGINE *e;
 
132
    VALUE obj;
 
133
 
 
134
    if (!(e = ENGINE_new())) {
 
135
       ossl_raise(eEngineError, NULL);
 
136
    }
 
137
    WrapEngine(klass, obj, e);
 
138
 
 
139
    return obj;
 
140
}
 
141
 
 
142
static VALUE
 
143
ossl_engine_get_id(VALUE self)
 
144
{
 
145
    ENGINE *e;
 
146
    GetEngine(self, e);
 
147
    return rb_str_new2(ENGINE_get_id(e));
 
148
}
 
149
 
 
150
static VALUE
 
151
ossl_engine_get_name(VALUE self)
 
152
{
 
153
    ENGINE *e;
 
154
    GetEngine(self, e);
 
155
    return rb_str_new2(ENGINE_get_name(e));
 
156
}
 
157
 
 
158
static VALUE
 
159
ossl_engine_finish(VALUE self)
 
160
{
 
161
    ENGINE *e;
 
162
 
 
163
    GetEngine(self, e);
 
164
    if(!ENGINE_finish(e)) ossl_raise(eEngineError, NULL);
 
165
 
 
166
    return Qnil;
 
167
}
 
168
 
 
169
static VALUE
 
170
ossl_engine_get_cipher(VALUE self, VALUE name)
 
171
{
 
172
#if defined(HAVE_ENGINE_GET_CIPHER)
 
173
    ENGINE *e;
 
174
    const EVP_CIPHER *ciph, *tmp;
 
175
    char *s;
 
176
    int nid;
 
177
 
 
178
    s = StringValuePtr(name);
 
179
    tmp = EVP_get_cipherbyname(s);
 
180
    if(!tmp) ossl_raise(eEngineError, "no such cipher `%s'", s);
 
181
    nid = EVP_CIPHER_nid(tmp);
 
182
    GetEngine(self, e);
 
183
    ciph = ENGINE_get_cipher(e, nid);
 
184
    if(!ciph) ossl_raise(eEngineError, NULL);
 
185
 
 
186
    return ossl_cipher_new(ciph);
 
187
#else
 
188
    rb_notimplement();
 
189
#endif
 
190
}
 
191
 
 
192
static VALUE
 
193
ossl_engine_get_digest(VALUE self, VALUE name)
 
194
{
 
195
#if defined(HAVE_ENGINE_GET_DIGEST)
 
196
    ENGINE *e;
 
197
    const EVP_MD *md, *tmp;
 
198
    char *s;
 
199
    int nid;
 
200
 
 
201
    s = StringValuePtr(name);
 
202
    tmp = EVP_get_digestbyname(s);
 
203
    if(!tmp) ossl_raise(eEngineError, "no such digest `%s'", s);
 
204
    nid = EVP_MD_nid(tmp);
 
205
    GetEngine(self, e);
 
206
    md = ENGINE_get_digest(e, nid);
 
207
    if(!md) ossl_raise(eEngineError, NULL);
 
208
 
 
209
    return ossl_digest_new(md);
 
210
#else
 
211
    rb_notimplement();
 
212
#endif
 
213
}
 
214
 
 
215
static VALUE
 
216
ossl_engine_load_privkey(int argc, VALUE *argv, VALUE self)
 
217
{
 
218
    ENGINE *e;
 
219
    EVP_PKEY *pkey;
 
220
    VALUE id, data, obj;
 
221
    char *sid, *sdata;
 
222
 
 
223
    rb_scan_args(argc, argv, "02", &id, &data);
 
224
    sid = NIL_P(id) ? NULL : StringValuePtr(id);
 
225
    sdata = NIL_P(data) ? NULL : StringValuePtr(data);
 
226
    GetEngine(self, e);
 
227
#if OPENSSL_VERSION_NUMBER < 0x00907000L
 
228
    pkey = ENGINE_load_private_key(e, sid, sdata);
 
229
#else
 
230
    pkey = ENGINE_load_private_key(e, sid, NULL, sdata);
 
231
#endif
 
232
    if (!pkey) ossl_raise(eEngineError, NULL);
 
233
    obj = ossl_pkey_new(pkey);
 
234
    OSSL_PKEY_SET_PRIVATE(obj);
 
235
 
 
236
    return obj;
 
237
}
 
238
 
 
239
static VALUE
 
240
ossl_engine_load_pubkey(int argc, VALUE *argv, VALUE self)
 
241
{
 
242
    ENGINE *e;
 
243
    EVP_PKEY *pkey;
 
244
    VALUE id, data;
 
245
    char *sid, *sdata;
 
246
 
 
247
    rb_scan_args(argc, argv, "02", &id, &data);
 
248
    sid = NIL_P(id) ? NULL : StringValuePtr(id);
 
249
    sdata = NIL_P(data) ? NULL : StringValuePtr(data);
 
250
    GetEngine(self, e);
 
251
#if OPENSSL_VERSION_NUMBER < 0x00907000L
 
252
    pkey = ENGINE_load_public_key(e, sid, sdata);
 
253
#else
 
254
    pkey = ENGINE_load_public_key(e, sid, NULL, sdata);
 
255
#endif
 
256
    if (!pkey) ossl_raise(eEngineError, NULL);
 
257
 
 
258
    return ossl_pkey_new(pkey);
 
259
}
 
260
 
 
261
static VALUE
 
262
ossl_engine_set_default(VALUE self, VALUE flag)
 
263
{
 
264
    ENGINE *e;
 
265
    int f = NUM2INT(flag);
 
266
 
 
267
    GetEngine(self, e);
 
268
    ENGINE_set_default(e, f);
 
269
 
 
270
    return Qtrue;
 
271
}
 
272
 
 
273
static VALUE
 
274
ossl_engine_ctrl_cmd(int argc, VALUE *argv, VALUE self)
 
275
{
 
276
    ENGINE *e;
 
277
    VALUE cmd, val;
 
278
    int ret;
 
279
 
 
280
    GetEngine(self, e);
 
281
    rb_scan_args(argc, argv, "11", &cmd, &val);
 
282
    StringValue(cmd);
 
283
    if (!NIL_P(val)) StringValue(val);
 
284
    ret = ENGINE_ctrl_cmd_string(e, RSTRING(cmd)->ptr,
 
285
                                 NIL_P(val) ? NULL : RSTRING(val)->ptr, 0);
 
286
    if (!ret) ossl_raise(eEngineError, NULL);
 
287
 
 
288
    return self;
 
289
}
 
290
 
 
291
static VALUE
 
292
ossl_engine_cmd_flag_to_name(int flag)
 
293
{
 
294
    switch(flag){
 
295
    case ENGINE_CMD_FLAG_NUMERIC:  return rb_str_new2("NUMERIC");
 
296
    case ENGINE_CMD_FLAG_STRING:   return rb_str_new2("STRING");
 
297
    case ENGINE_CMD_FLAG_NO_INPUT: return rb_str_new2("NO_INPUT");
 
298
    case ENGINE_CMD_FLAG_INTERNAL: return rb_str_new2("INTERNAL");
 
299
    default: return rb_str_new2("UNKNOWN");
 
300
    }
 
301
}
 
302
 
 
303
static VALUE
 
304
ossl_engine_get_cmds(VALUE self)
 
305
{
 
306
    ENGINE *e;
 
307
    const ENGINE_CMD_DEFN *defn, *p;
 
308
    VALUE ary, tmp;
 
309
 
 
310
    GetEngine(self, e);
 
311
    ary = rb_ary_new();
 
312
    if ((defn = ENGINE_get_cmd_defns(e)) != NULL){
 
313
        for (p = defn; p->cmd_num > 0; p++){
 
314
            tmp = rb_ary_new();
 
315
            rb_ary_push(tmp, rb_str_new2(p->cmd_name));
 
316
            rb_ary_push(tmp, rb_str_new2(p->cmd_desc));
 
317
            rb_ary_push(tmp, ossl_engine_cmd_flag_to_name(p->cmd_flags));
 
318
            rb_ary_push(ary, tmp);
 
319
        }
 
320
    }
 
321
 
 
322
    return ary;
 
323
}
 
324
 
 
325
static VALUE
 
326
ossl_engine_inspect(VALUE self)
 
327
{
 
328
    VALUE str;
 
329
    char *cname = rb_class2name(rb_obj_class(self));
 
330
    
 
331
    str = rb_str_new2("#<");
 
332
    rb_str_cat2(str, cname);
 
333
    rb_str_cat2(str, " id=\"");
 
334
    rb_str_append(str, ossl_engine_get_id(self));
 
335
    rb_str_cat2(str, "\" name=\"");
 
336
    rb_str_append(str, ossl_engine_get_name(self));
 
337
    rb_str_cat2(str, "\">");
 
338
 
 
339
    return str;
 
340
}
 
341
 
 
342
#define DefEngineConst(x) rb_define_const(cEngine, #x, INT2NUM(ENGINE_##x))
 
343
 
 
344
void
 
345
Init_ossl_engine()
 
346
{
 
347
    cEngine = rb_define_class_under(mOSSL, "Engine", rb_cObject);
 
348
    eEngineError = rb_define_class_under(cEngine, "EngineError", eOSSLError);
 
349
 
 
350
    rb_define_alloc_func(cEngine, ossl_engine_s_alloc);
 
351
    rb_define_singleton_method(cEngine, "load", ossl_engine_s_load, -1);
 
352
    rb_define_singleton_method(cEngine, "cleanup", ossl_engine_s_cleanup, 0);
 
353
    rb_define_singleton_method(cEngine, "engines", ossl_engine_s_engines, 0);
 
354
    rb_define_singleton_method(cEngine, "by_id", ossl_engine_s_by_id, 1);
 
355
    rb_undef_method(CLASS_OF(cEngine), "new");
 
356
 
 
357
    rb_define_method(cEngine, "id", ossl_engine_get_id, 0);
 
358
    rb_define_method(cEngine, "name", ossl_engine_get_name, 0);
 
359
    rb_define_method(cEngine, "finish", ossl_engine_finish, 0);
 
360
    rb_define_method(cEngine, "cipher", ossl_engine_get_cipher, 1);
 
361
    rb_define_method(cEngine, "digest",  ossl_engine_get_digest, 1);
 
362
    rb_define_method(cEngine, "load_private_key", ossl_engine_load_privkey, -1);
 
363
    rb_define_method(cEngine, "load_public_key", ossl_engine_load_pubkey, -1);
 
364
    rb_define_method(cEngine, "set_default", ossl_engine_set_default, 1);
 
365
    rb_define_method(cEngine, "ctrl_cmd", ossl_engine_ctrl_cmd, -1);
 
366
    rb_define_method(cEngine, "cmds", ossl_engine_get_cmds, 0);
 
367
    rb_define_method(cEngine, "inspect", ossl_engine_inspect, 0);
 
368
 
 
369
    DefEngineConst(METHOD_RSA);
 
370
    DefEngineConst(METHOD_DSA);
 
371
    DefEngineConst(METHOD_DH);
 
372
    DefEngineConst(METHOD_RAND);
 
373
#ifdef ENGINE_METHOD_BN_MOD_EXP
 
374
    DefEngineConst(METHOD_BN_MOD_EXP);
 
375
#endif
 
376
#ifdef ENGINE_METHOD_BN_MOD_EXP_CRT
 
377
    DefEngineConst(METHOD_BN_MOD_EXP_CRT);
 
378
#endif
 
379
#ifdef ENGINE_METHOD_CIPHERS
 
380
    DefEngineConst(METHOD_CIPHERS);
 
381
#endif
 
382
#ifdef ENGINE_METHOD_DIGESTS
 
383
    DefEngineConst(METHOD_DIGESTS);
 
384
#endif
 
385
    DefEngineConst(METHOD_ALL);
 
386
    DefEngineConst(METHOD_NONE);
 
387
}
 
388
#else
 
389
void
 
390
Init_ossl_engine()
 
391
{
 
392
}
 
393
#endif