static int HasNoPrivateKey(RSA* rsa) { if (rsa == nullptr) return 1; // Shared pointer, don't free. const RSA_METHOD* meth = RSA_get_method(rsa); // The method has descibed itself as having the private key external to the structure. // That doesn't mean it's actually present, but we can't tell. if (meth->flags & RSA_FLAG_EXT_PKEY) return 0; // In the event that there's a middle-ground where we report failure when success is expected, // one could do something like check if the RSA_METHOD intercepts all private key operations: // // * meth->rsa_priv_enc // * meth->rsa_priv_dec // * meth->rsa_sign (in 1.0.x this is only respected if the RSA_FLAG_SIGN_VER flag is asserted) // // But, for now, leave it at the EXT_PKEY flag test. // The module is documented as accepting either d or the full set of CRT parameters (p, q, dp, dq, qInv) // So if we see d, we're good. Otherwise, if any of the rest are missing, we're public-only. if (rsa->d != nullptr) return 0; if (rsa->p == nullptr || rsa->q == nullptr || rsa->dmp1 == nullptr || rsa->dmq1 == nullptr || rsa->iqmp == nullptr) return 1; return 0; }
static void convert_rsa_to_rsa1(Key * in, Key * out) { struct sc_priv_data *priv; out->rsa->flags = in->rsa->flags; out->flags = in->flags; RSA_set_method(out->rsa, RSA_get_method(in->rsa)); BN_copy(out->rsa->n, in->rsa->n); BN_copy(out->rsa->e, in->rsa->e); priv = RSA_get_app_data(in->rsa); priv->ref_count++; RSA_set_app_data(out->rsa, priv); return; }