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