@@ -4135,6 +4135,126 @@ static EVP_PKEY *php_openssl_pkey_init_dh(zval *data, bool *is_private)
4135
4135
#endif
4136
4136
}
4137
4137
4138
+ #ifdef HAVE_EVP_PKEY_EC
4139
+ static bool php_openssl_pkey_init_legacy_ec (EC_KEY * eckey , zval * data , bool * is_private ) {
4140
+ EC_GROUP * group = NULL ;
4141
+ EC_POINT * pnt = NULL ;
4142
+ BIGNUM * d = NULL ;
4143
+ zval * bn ;
4144
+ zval * x ;
4145
+ zval * y ;
4146
+
4147
+ if ((bn = zend_hash_str_find (Z_ARRVAL_P (data ), "curve_name" , sizeof ("curve_name" ) - 1 )) != NULL &&
4148
+ Z_TYPE_P (bn ) == IS_STRING ) {
4149
+ int nid = OBJ_sn2nid (Z_STRVAL_P (bn ));
4150
+ if (nid != NID_undef ) {
4151
+ group = EC_GROUP_new_by_curve_name (nid );
4152
+ if (!group ) {
4153
+ php_openssl_store_errors ();
4154
+ goto clean_exit ;
4155
+ }
4156
+ EC_GROUP_set_asn1_flag (group , OPENSSL_EC_NAMED_CURVE );
4157
+ EC_GROUP_set_point_conversion_form (group , POINT_CONVERSION_UNCOMPRESSED );
4158
+ if (!EC_KEY_set_group (eckey , group )) {
4159
+ php_openssl_store_errors ();
4160
+ goto clean_exit ;
4161
+ }
4162
+ }
4163
+ }
4164
+
4165
+ if (group == NULL ) {
4166
+ php_error_docref (NULL , E_WARNING , "Unknown curve name" );
4167
+ goto clean_exit ;
4168
+ }
4169
+
4170
+ // The public key 'pnt' can be calculated from 'd' or is defined by 'x' and 'y'
4171
+ * is_private = false;
4172
+ if ((bn = zend_hash_str_find (Z_ARRVAL_P (data ), "d" , sizeof ("d" ) - 1 )) != NULL &&
4173
+ Z_TYPE_P (bn ) == IS_STRING ) {
4174
+ * is_private = true;
4175
+ d = BN_bin2bn ((unsigned char * ) Z_STRVAL_P (bn ), Z_STRLEN_P (bn ), NULL );
4176
+ if (!EC_KEY_set_private_key (eckey , d )) {
4177
+ php_openssl_store_errors ();
4178
+ goto clean_exit ;
4179
+ }
4180
+ // Calculate the public key by multiplying the Point Q with the public key
4181
+ // P = d * Q
4182
+ pnt = EC_POINT_new (group );
4183
+ if (!pnt || !EC_POINT_mul (group , pnt , d , NULL , NULL , NULL )) {
4184
+ php_openssl_store_errors ();
4185
+ goto clean_exit ;
4186
+ }
4187
+
4188
+ BN_free (d );
4189
+ } else if ((x = zend_hash_str_find (Z_ARRVAL_P (data ), "x" , sizeof ("x" ) - 1 )) != NULL &&
4190
+ Z_TYPE_P (x ) == IS_STRING &&
4191
+ (y = zend_hash_str_find (Z_ARRVAL_P (data ), "y" , sizeof ("y" ) - 1 )) != NULL &&
4192
+ Z_TYPE_P (y ) == IS_STRING ) {
4193
+ pnt = EC_POINT_new (group );
4194
+ if (pnt == NULL ) {
4195
+ php_openssl_store_errors ();
4196
+ goto clean_exit ;
4197
+ }
4198
+ if (!EC_POINT_set_affine_coordinates_GFp (
4199
+ group , pnt , BN_bin2bn ((unsigned char * ) Z_STRVAL_P (x ), Z_STRLEN_P (x ), NULL ),
4200
+ BN_bin2bn ((unsigned char * ) Z_STRVAL_P (y ), Z_STRLEN_P (y ), NULL ), NULL )) {
4201
+ php_openssl_store_errors ();
4202
+ goto clean_exit ;
4203
+ }
4204
+ }
4205
+
4206
+ if (pnt != NULL ) {
4207
+ if (!EC_KEY_set_public_key (eckey , pnt )) {
4208
+ php_openssl_store_errors ();
4209
+ goto clean_exit ;
4210
+ }
4211
+ EC_POINT_free (pnt );
4212
+ pnt = NULL ;
4213
+ }
4214
+
4215
+ if (!EC_KEY_check_key (eckey )) {
4216
+ PHP_OPENSSL_RAND_ADD_TIME ();
4217
+ EC_KEY_generate_key (eckey );
4218
+ php_openssl_store_errors ();
4219
+ }
4220
+ if (EC_KEY_check_key (eckey )) {
4221
+ return true;
4222
+ } else {
4223
+ php_openssl_store_errors ();
4224
+ }
4225
+
4226
+ clean_exit :
4227
+ BN_free (d );
4228
+ EC_POINT_free (pnt );
4229
+ EC_GROUP_free (group );
4230
+ return false;
4231
+ }
4232
+
4233
+ static EVP_PKEY * php_openssl_pkey_init_ec (zval * data , bool * is_private ) {
4234
+ EVP_PKEY * pkey = EVP_PKEY_new ();
4235
+ if (!pkey ) {
4236
+ php_openssl_store_errors ();
4237
+ return NULL ;
4238
+ }
4239
+
4240
+ EC_KEY * ec = EC_KEY_new ();
4241
+ if (!ec ) {
4242
+ EVP_PKEY_free (pkey );
4243
+ return NULL ;
4244
+ }
4245
+
4246
+ if (!php_openssl_pkey_init_legacy_ec (ec , data , is_private )
4247
+ || !EVP_PKEY_assign_EC_KEY (pkey , ec )) {
4248
+ php_openssl_store_errors ();
4249
+ EVP_PKEY_free (pkey );
4250
+ EC_KEY_free (ec );
4251
+ return NULL ;
4252
+ }
4253
+
4254
+ return pkey ;
4255
+ }
4256
+ #endif
4257
+
4138
4258
/* {{{ Generates a new private key */
4139
4259
PHP_FUNCTION (openssl_pkey_new )
4140
4260
{
@@ -4190,120 +4310,13 @@ PHP_FUNCTION(openssl_pkey_new)
4190
4310
#ifdef HAVE_EVP_PKEY_EC
4191
4311
} else if ((data = zend_hash_str_find (Z_ARRVAL_P (args ), "ec" , sizeof ("ec" ) - 1 )) != NULL &&
4192
4312
Z_TYPE_P (data ) == IS_ARRAY ) {
4193
- EC_KEY * eckey = NULL ;
4194
- EC_GROUP * group = NULL ;
4195
- EC_POINT * pnt = NULL ;
4196
- BIGNUM * d = NULL ;
4197
- pkey = EVP_PKEY_new ();
4198
- if (pkey ) {
4199
- eckey = EC_KEY_new ();
4200
- if (eckey ) {
4201
- bool is_private = false;
4202
- EC_GROUP * group = NULL ;
4203
- zval * bn ;
4204
- zval * x ;
4205
- zval * y ;
4206
-
4207
- if ((bn = zend_hash_str_find (Z_ARRVAL_P (data ), "curve_name" , sizeof ("curve_name" ) - 1 )) != NULL &&
4208
- Z_TYPE_P (bn ) == IS_STRING ) {
4209
- int nid = OBJ_sn2nid (Z_STRVAL_P (bn ));
4210
- if (nid != NID_undef ) {
4211
- group = EC_GROUP_new_by_curve_name (nid );
4212
- if (!group ) {
4213
- php_openssl_store_errors ();
4214
- goto clean_exit ;
4215
- }
4216
- EC_GROUP_set_asn1_flag (group , OPENSSL_EC_NAMED_CURVE );
4217
- EC_GROUP_set_point_conversion_form (group , POINT_CONVERSION_UNCOMPRESSED );
4218
- if (!EC_KEY_set_group (eckey , group )) {
4219
- php_openssl_store_errors ();
4220
- goto clean_exit ;
4221
- }
4222
- }
4223
- }
4224
-
4225
- if (group == NULL ) {
4226
- php_error_docref (NULL , E_WARNING , "Unknown curve name" );
4227
- goto clean_exit ;
4228
- }
4229
-
4230
- // The public key 'pnt' can be calculated from 'd' or is defined by 'x' and 'y'
4231
- if ((bn = zend_hash_str_find (Z_ARRVAL_P (data ), "d" , sizeof ("d" ) - 1 )) != NULL &&
4232
- Z_TYPE_P (bn ) == IS_STRING ) {
4233
- is_private = true;
4234
- d = BN_bin2bn ((unsigned char * ) Z_STRVAL_P (bn ), Z_STRLEN_P (bn ), NULL );
4235
- if (!EC_KEY_set_private_key (eckey , d )) {
4236
- php_openssl_store_errors ();
4237
- goto clean_exit ;
4238
- }
4239
- // Calculate the public key by multiplying the Point Q with the public key
4240
- // P = d * Q
4241
- pnt = EC_POINT_new (group );
4242
- if (!pnt || !EC_POINT_mul (group , pnt , d , NULL , NULL , NULL )) {
4243
- php_openssl_store_errors ();
4244
- goto clean_exit ;
4245
- }
4246
-
4247
- BN_free (d );
4248
- } else if ((x = zend_hash_str_find (Z_ARRVAL_P (data ), "x" , sizeof ("x" ) - 1 )) != NULL &&
4249
- Z_TYPE_P (x ) == IS_STRING &&
4250
- (y = zend_hash_str_find (Z_ARRVAL_P (data ), "y" , sizeof ("y" ) - 1 )) != NULL &&
4251
- Z_TYPE_P (y ) == IS_STRING ) {
4252
- pnt = EC_POINT_new (group );
4253
- if (pnt == NULL ) {
4254
- php_openssl_store_errors ();
4255
- goto clean_exit ;
4256
- }
4257
- if (!EC_POINT_set_affine_coordinates_GFp (
4258
- group , pnt , BN_bin2bn ((unsigned char * ) Z_STRVAL_P (x ), Z_STRLEN_P (x ), NULL ),
4259
- BN_bin2bn ((unsigned char * ) Z_STRVAL_P (y ), Z_STRLEN_P (y ), NULL ), NULL )) {
4260
- php_openssl_store_errors ();
4261
- goto clean_exit ;
4262
- }
4263
- }
4264
-
4265
- if (pnt != NULL ) {
4266
- if (!EC_KEY_set_public_key (eckey , pnt )) {
4267
- php_openssl_store_errors ();
4268
- goto clean_exit ;
4269
- }
4270
- EC_POINT_free (pnt );
4271
- pnt = NULL ;
4272
- }
4273
-
4274
- if (!EC_KEY_check_key (eckey )) {
4275
- PHP_OPENSSL_RAND_ADD_TIME ();
4276
- EC_KEY_generate_key (eckey );
4277
- php_openssl_store_errors ();
4278
- }
4279
- if (EC_KEY_check_key (eckey ) && EVP_PKEY_assign_EC_KEY (pkey , eckey )) {
4280
- EC_GROUP_free (group );
4281
- php_openssl_pkey_object_init (return_value , pkey , is_private );
4282
- return ;
4283
- } else {
4284
- php_openssl_store_errors ();
4285
- }
4286
- } else {
4287
- php_openssl_store_errors ();
4288
- }
4289
- } else {
4290
- php_openssl_store_errors ();
4291
- }
4292
- clean_exit :
4293
- if (d != NULL ) {
4294
- BN_free (d );
4295
- }
4296
- if (pnt != NULL ) {
4297
- EC_POINT_free (pnt );
4298
- }
4299
- if (group != NULL ) {
4300
- EC_GROUP_free (group );
4301
- }
4302
- if (eckey != NULL ) {
4303
- EC_KEY_free (eckey );
4313
+ bool is_private ;
4314
+ pkey = php_openssl_pkey_init_ec (data , & is_private );
4315
+ if (!pkey ) {
4316
+ RETURN_FALSE ;
4304
4317
}
4305
- EVP_PKEY_free ( pkey );
4306
- RETURN_FALSE ;
4318
+ php_openssl_pkey_object_init ( return_value , pkey , is_private );
4319
+ return ;
4307
4320
#endif
4308
4321
}
4309
4322
}
0 commit comments