@@ -95,34 +95,30 @@ const rb_data_type_t ossl_evp_pkey_type = {
95
95
static VALUE
96
96
pkey_new0 (EVP_PKEY * pkey )
97
97
{
98
- VALUE obj ;
98
+ VALUE klass , obj ;
99
99
int type ;
100
100
101
101
if (!pkey || (type = EVP_PKEY_base_id (pkey )) == EVP_PKEY_NONE )
102
102
ossl_raise (rb_eRuntimeError , "pkey is empty" );
103
103
104
104
switch (type ) {
105
105
#if !defined(OPENSSL_NO_RSA )
106
- case EVP_PKEY_RSA :
107
- return ossl_rsa_new (pkey );
106
+ case EVP_PKEY_RSA : klass = cRSA ; break ;
108
107
#endif
109
108
#if !defined(OPENSSL_NO_DSA )
110
- case EVP_PKEY_DSA :
111
- return ossl_dsa_new (pkey );
109
+ case EVP_PKEY_DSA : klass = cDSA ; break ;
112
110
#endif
113
111
#if !defined(OPENSSL_NO_DH )
114
- case EVP_PKEY_DH :
115
- return ossl_dh_new (pkey );
112
+ case EVP_PKEY_DH : klass = cDH ; break ;
116
113
#endif
117
114
#if !defined(OPENSSL_NO_EC )
118
- case EVP_PKEY_EC :
119
- return ossl_ec_new (pkey );
115
+ case EVP_PKEY_EC : klass = cEC ; break ;
120
116
#endif
121
- default :
122
- obj = NewPKey (cPKey );
123
- SetPKey (obj , pkey );
124
- return obj ;
117
+ default : klass = cPKey ; break ;
125
118
}
119
+ obj = NewPKey (klass );
120
+ SetPKey (obj , pkey );
121
+ return obj ;
126
122
}
127
123
128
124
VALUE
@@ -140,6 +136,35 @@ ossl_pkey_new(EVP_PKEY *pkey)
140
136
return obj ;
141
137
}
142
138
139
+ EVP_PKEY *
140
+ ossl_pkey_read_generic (BIO * bio , VALUE pass )
141
+ {
142
+ void * ppass = (void * )pass ;
143
+ EVP_PKEY * pkey ;
144
+
145
+ if ((pkey = d2i_PrivateKey_bio (bio , NULL )))
146
+ goto out ;
147
+ OSSL_BIO_reset (bio );
148
+ if ((pkey = d2i_PKCS8PrivateKey_bio (bio , NULL , ossl_pem_passwd_cb , ppass )))
149
+ goto out ;
150
+ OSSL_BIO_reset (bio );
151
+ if ((pkey = d2i_PUBKEY_bio (bio , NULL )))
152
+ goto out ;
153
+ OSSL_BIO_reset (bio );
154
+ /* PEM_read_bio_PrivateKey() also parses PKCS #8 formats */
155
+ if ((pkey = PEM_read_bio_PrivateKey (bio , NULL , ossl_pem_passwd_cb , ppass )))
156
+ goto out ;
157
+ OSSL_BIO_reset (bio );
158
+ if ((pkey = PEM_read_bio_PUBKEY (bio , NULL , NULL , NULL )))
159
+ goto out ;
160
+ OSSL_BIO_reset (bio );
161
+ if ((pkey = PEM_read_bio_Parameters (bio , NULL )))
162
+ goto out ;
163
+
164
+ out :
165
+ return pkey ;
166
+ }
167
+
143
168
/*
144
169
* call-seq:
145
170
* OpenSSL::PKey.read(string [, pwd ]) -> PKey
@@ -164,30 +189,11 @@ ossl_pkey_new_from_data(int argc, VALUE *argv, VALUE self)
164
189
VALUE data , pass ;
165
190
166
191
rb_scan_args (argc , argv , "11" , & data , & pass );
167
- pass = ossl_pem_passwd_value (pass );
168
-
169
192
bio = ossl_obj2bio (& data );
170
- if ((pkey = d2i_PrivateKey_bio (bio , NULL )))
171
- goto ok ;
172
- OSSL_BIO_reset (bio );
173
- if ((pkey = d2i_PKCS8PrivateKey_bio (bio , NULL , ossl_pem_passwd_cb , (void * )pass )))
174
- goto ok ;
175
- OSSL_BIO_reset (bio );
176
- if ((pkey = d2i_PUBKEY_bio (bio , NULL )))
177
- goto ok ;
178
- OSSL_BIO_reset (bio );
179
- /* PEM_read_bio_PrivateKey() also parses PKCS #8 formats */
180
- if ((pkey = PEM_read_bio_PrivateKey (bio , NULL , ossl_pem_passwd_cb , (void * )pass )))
181
- goto ok ;
182
- OSSL_BIO_reset (bio );
183
- if ((pkey = PEM_read_bio_PUBKEY (bio , NULL , NULL , NULL )))
184
- goto ok ;
185
-
186
- BIO_free (bio );
187
- ossl_raise (ePKeyError , "Could not parse PKey" );
188
-
189
- ok :
193
+ pkey = ossl_pkey_read_generic (bio , ossl_pem_passwd_value (pass ));
190
194
BIO_free (bio );
195
+ if (!pkey )
196
+ ossl_raise (ePKeyError , "Could not parse PKey" );
191
197
return ossl_pkey_new (pkey );
192
198
}
193
199
@@ -335,6 +341,52 @@ ossl_pkey_inspect(VALUE self)
335
341
OBJ_nid2sn (nid ));
336
342
}
337
343
344
+ VALUE
345
+ ossl_pkey_export_traditional (int argc , VALUE * argv , VALUE self , int to_der )
346
+ {
347
+ EVP_PKEY * pkey ;
348
+ VALUE cipher , pass ;
349
+ const EVP_CIPHER * enc = NULL ;
350
+ BIO * bio ;
351
+
352
+ GetPKey (self , pkey );
353
+ rb_scan_args (argc , argv , "02" , & cipher , & pass );
354
+ if (!NIL_P (cipher )) {
355
+ enc = ossl_evp_get_cipherbyname (cipher );
356
+ pass = ossl_pem_passwd_value (pass );
357
+ }
358
+
359
+ bio = BIO_new (BIO_s_mem ());
360
+ if (!bio )
361
+ ossl_raise (ePKeyError , "BIO_new" );
362
+ if (to_der ) {
363
+ if (!i2d_PrivateKey_bio (bio , pkey )) {
364
+ BIO_free (bio );
365
+ ossl_raise (ePKeyError , "i2d_PrivateKey_bio" );
366
+ }
367
+ }
368
+ else {
369
+ #if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER )
370
+ if (!PEM_write_bio_PrivateKey_traditional (bio , pkey , enc , NULL , 0 ,
371
+ ossl_pem_passwd_cb ,
372
+ (void * )pass )) {
373
+ #else
374
+ char pem_str [80 ];
375
+ const char * aname ;
376
+
377
+ EVP_PKEY_asn1_get0_info (NULL , NULL , NULL , NULL , & aname , pkey -> ameth );
378
+ snprintf (pem_str , sizeof (pem_str ), "%s PRIVATE KEY" , aname );
379
+ if (!PEM_ASN1_write_bio ((i2d_of_void * )i2d_PrivateKey , pem_str , bio ,
380
+ pkey , enc , NULL , 0 , ossl_pem_passwd_cb ,
381
+ (void * )pass )) {
382
+ #endif
383
+ BIO_free (bio );
384
+ ossl_raise (ePKeyError , "PEM_write_bio_PrivateKey_traditional" );
385
+ }
386
+ }
387
+ return ossl_membio2str (bio );
388
+ }
389
+
338
390
static VALUE
339
391
do_pkcs8_export (int argc , VALUE * argv , VALUE self , int to_der )
340
392
{
@@ -404,8 +456,8 @@ ossl_pkey_private_to_pem(int argc, VALUE *argv, VALUE self)
404
456
return do_pkcs8_export (argc , argv , self , 0 );
405
457
}
406
458
407
- static VALUE
408
- do_spki_export (VALUE self , int to_der )
459
+ VALUE
460
+ ossl_pkey_export_spki (VALUE self , int to_der )
409
461
{
410
462
EVP_PKEY * pkey ;
411
463
BIO * bio ;
@@ -438,7 +490,7 @@ do_spki_export(VALUE self, int to_der)
438
490
static VALUE
439
491
ossl_pkey_public_to_der (VALUE self )
440
492
{
441
- return do_spki_export (self , 1 );
493
+ return ossl_pkey_export_spki (self , 1 );
442
494
}
443
495
444
496
/*
@@ -450,7 +502,7 @@ ossl_pkey_public_to_der(VALUE self)
450
502
static VALUE
451
503
ossl_pkey_public_to_pem (VALUE self )
452
504
{
453
- return do_spki_export (self , 0 );
505
+ return ossl_pkey_export_spki (self , 0 );
454
506
}
455
507
456
508
/*
0 commit comments