00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "ossl.h"
00012
00013
00014
00015
00016 VALUE mPKey;
00017 VALUE cPKey;
00018 VALUE ePKeyError;
00019 ID id_private_q;
00020
00021
00022
00023
00024 void
00025 ossl_generate_cb(int p, int n, void *arg)
00026 {
00027 VALUE ary;
00028
00029 ary = rb_ary_new2(2);
00030 rb_ary_store(ary, 0, INT2NUM(p));
00031 rb_ary_store(ary, 1, INT2NUM(n));
00032
00033 rb_yield(ary);
00034 }
00035
00036 #if HAVE_BN_GENCB
00037
00038 int
00039 ossl_generate_cb_2(int p, int n, BN_GENCB *cb)
00040 {
00041 VALUE ary;
00042 struct ossl_generate_cb_arg *arg;
00043 int state;
00044
00045 arg = (struct ossl_generate_cb_arg *)cb->arg;
00046 if (arg->yield) {
00047 ary = rb_ary_new2(2);
00048 rb_ary_store(ary, 0, INT2NUM(p));
00049 rb_ary_store(ary, 1, INT2NUM(n));
00050
00051
00052
00053
00054 rb_protect(rb_yield, ary, &state);
00055 if (state) {
00056 arg->stop = 1;
00057 arg->state = state;
00058 }
00059 }
00060 if (arg->stop) return 0;
00061 return 1;
00062 }
00063
00064 void
00065 ossl_generate_cb_stop(void *ptr)
00066 {
00067 struct ossl_generate_cb_arg *arg = (struct ossl_generate_cb_arg *)ptr;
00068 arg->stop = 1;
00069 }
00070 #endif
00071
00072
00073
00074
00075 VALUE
00076 ossl_pkey_new(EVP_PKEY *pkey)
00077 {
00078 if (!pkey) {
00079 ossl_raise(ePKeyError, "Cannot make new key from NULL.");
00080 }
00081 switch (EVP_PKEY_type(pkey->type)) {
00082 #if !defined(OPENSSL_NO_RSA)
00083 case EVP_PKEY_RSA:
00084 return ossl_rsa_new(pkey);
00085 #endif
00086 #if !defined(OPENSSL_NO_DSA)
00087 case EVP_PKEY_DSA:
00088 return ossl_dsa_new(pkey);
00089 #endif
00090 #if !defined(OPENSSL_NO_DH)
00091 case EVP_PKEY_DH:
00092 return ossl_dh_new(pkey);
00093 #endif
00094 #if !defined(OPENSSL_NO_EC) && (OPENSSL_VERSION_NUMBER >= 0x0090802fL)
00095 case EVP_PKEY_EC:
00096 return ossl_ec_new(pkey);
00097 #endif
00098 default:
00099 ossl_raise(ePKeyError, "unsupported key type");
00100 }
00101
00102 UNREACHABLE;
00103 }
00104
00105 VALUE
00106 ossl_pkey_new_from_file(VALUE filename)
00107 {
00108 FILE *fp;
00109 EVP_PKEY *pkey;
00110
00111 SafeStringValue(filename);
00112 if (!(fp = fopen(RSTRING_PTR(filename), "r"))) {
00113 ossl_raise(ePKeyError, "%s", strerror(errno));
00114 }
00115 rb_fd_fix_cloexec(fileno(fp));
00116
00117 pkey = PEM_read_PrivateKey(fp, NULL, ossl_pem_passwd_cb, NULL);
00118 fclose(fp);
00119 if (!pkey) {
00120 ossl_raise(ePKeyError, NULL);
00121 }
00122
00123 return ossl_pkey_new(pkey);
00124 }
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139 static VALUE
00140 ossl_pkey_new_from_data(int argc, VALUE *argv, VALUE self)
00141 {
00142 EVP_PKEY *pkey;
00143 BIO *bio;
00144 VALUE data, pass;
00145 char *passwd = NULL;
00146
00147 rb_scan_args(argc, argv, "11", &data, &pass);
00148
00149 bio = ossl_obj2bio(data);
00150 if (!(pkey = d2i_PrivateKey_bio(bio, NULL))) {
00151 OSSL_BIO_reset(bio);
00152 if (!NIL_P(pass)) {
00153 passwd = StringValuePtr(pass);
00154 }
00155 if (!(pkey = PEM_read_bio_PrivateKey(bio, NULL, ossl_pem_passwd_cb, passwd))) {
00156 OSSL_BIO_reset(bio);
00157 if (!(pkey = d2i_PUBKEY_bio(bio, NULL))) {
00158 OSSL_BIO_reset(bio);
00159 if (!NIL_P(pass)) {
00160 passwd = StringValuePtr(pass);
00161 }
00162 pkey = PEM_read_bio_PUBKEY(bio, NULL, ossl_pem_passwd_cb, passwd);
00163 }
00164 }
00165 }
00166
00167 BIO_free(bio);
00168 if (!pkey)
00169 ossl_raise(rb_eArgError, "Could not parse PKey");
00170 return ossl_pkey_new(pkey);
00171 }
00172
00173 EVP_PKEY *
00174 GetPKeyPtr(VALUE obj)
00175 {
00176 EVP_PKEY *pkey;
00177
00178 SafeGetPKey(obj, pkey);
00179
00180 return pkey;
00181 }
00182
00183 EVP_PKEY *
00184 GetPrivPKeyPtr(VALUE obj)
00185 {
00186 EVP_PKEY *pkey;
00187
00188 if (rb_funcall(obj, id_private_q, 0, NULL) != Qtrue) {
00189 ossl_raise(rb_eArgError, "Private key is needed.");
00190 }
00191 SafeGetPKey(obj, pkey);
00192
00193 return pkey;
00194 }
00195
00196 EVP_PKEY *
00197 DupPKeyPtr(VALUE obj)
00198 {
00199 EVP_PKEY *pkey;
00200
00201 SafeGetPKey(obj, pkey);
00202 CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
00203
00204 return pkey;
00205 }
00206
00207 EVP_PKEY *
00208 DupPrivPKeyPtr(VALUE obj)
00209 {
00210 EVP_PKEY *pkey;
00211
00212 if (rb_funcall(obj, id_private_q, 0, NULL) != Qtrue) {
00213 ossl_raise(rb_eArgError, "Private key is needed.");
00214 }
00215 SafeGetPKey(obj, pkey);
00216 CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
00217
00218 return pkey;
00219 }
00220
00221
00222
00223
00224 static VALUE
00225 ossl_pkey_alloc(VALUE klass)
00226 {
00227 EVP_PKEY *pkey;
00228 VALUE obj;
00229
00230 if (!(pkey = EVP_PKEY_new())) {
00231 ossl_raise(ePKeyError, NULL);
00232 }
00233 WrapPKey(klass, obj, pkey);
00234
00235 return obj;
00236 }
00237
00238
00239
00240
00241
00242
00243
00244
00245 static VALUE
00246 ossl_pkey_initialize(VALUE self)
00247 {
00248 if (rb_obj_is_instance_of(self, cPKey)) {
00249 ossl_raise(rb_eNotImpError, "OpenSSL::PKey::PKey is an abstract class.");
00250 }
00251 return self;
00252 }
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271 static VALUE
00272 ossl_pkey_sign(VALUE self, VALUE digest, VALUE data)
00273 {
00274 EVP_PKEY *pkey;
00275 EVP_MD_CTX ctx;
00276 unsigned int buf_len;
00277 VALUE str;
00278
00279 if (rb_funcall(self, id_private_q, 0, NULL) != Qtrue) {
00280 ossl_raise(rb_eArgError, "Private key is needed.");
00281 }
00282 GetPKey(self, pkey);
00283 EVP_SignInit(&ctx, GetDigestPtr(digest));
00284 StringValue(data);
00285 EVP_SignUpdate(&ctx, RSTRING_PTR(data), RSTRING_LEN(data));
00286 str = rb_str_new(0, EVP_PKEY_size(pkey)+16);
00287 if (!EVP_SignFinal(&ctx, (unsigned char *)RSTRING_PTR(str), &buf_len, pkey))
00288 ossl_raise(ePKeyError, NULL);
00289 assert((long)buf_len <= RSTRING_LEN(str));
00290 rb_str_set_len(str, buf_len);
00291
00292 return str;
00293 }
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316 static VALUE
00317 ossl_pkey_verify(VALUE self, VALUE digest, VALUE sig, VALUE data)
00318 {
00319 EVP_PKEY *pkey;
00320 EVP_MD_CTX ctx;
00321 int result;
00322
00323 GetPKey(self, pkey);
00324 StringValue(sig);
00325 StringValue(data);
00326 EVP_VerifyInit(&ctx, GetDigestPtr(digest));
00327 EVP_VerifyUpdate(&ctx, RSTRING_PTR(data), RSTRING_LEN(data));
00328 result = EVP_VerifyFinal(&ctx, (unsigned char *)RSTRING_PTR(sig), RSTRING_LENINT(sig), pkey);
00329 EVP_MD_CTX_cleanup(&ctx);
00330 switch (result) {
00331 case 0:
00332 return Qfalse;
00333 case 1:
00334 return Qtrue;
00335 default:
00336 ossl_raise(ePKeyError, NULL);
00337 }
00338 return Qnil;
00339 }
00340
00341
00342
00343
00344 void
00345 Init_ossl_pkey()
00346 {
00347 #if 0
00348 mOSSL = rb_define_module("OpenSSL");
00349 #endif
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402 mPKey = rb_define_module_under(mOSSL, "PKey");
00403
00404
00405
00406
00407
00408 ePKeyError = rb_define_class_under(mPKey, "PKeyError", eOSSLError);
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419 cPKey = rb_define_class_under(mPKey, "PKey", rb_cObject);
00420
00421 rb_define_module_function(mPKey, "read", ossl_pkey_new_from_data, -1);
00422
00423 rb_define_alloc_func(cPKey, ossl_pkey_alloc);
00424 rb_define_method(cPKey, "initialize", ossl_pkey_initialize, 0);
00425
00426 rb_define_method(cPKey, "sign", ossl_pkey_sign, 2);
00427 rb_define_method(cPKey, "verify", ossl_pkey_verify, 3);
00428
00429 id_private_q = rb_intern("private?");
00430
00431
00432
00433
00434 Init_ossl_rsa();
00435 Init_ossl_dsa();
00436 Init_ossl_dh();
00437 Init_ossl_ec();
00438 }
00439
00440