EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp, long length) { X509_PUBKEY *xpk; EVP_PKEY *pktmp; const unsigned char *q; q = *pp; xpk = d2i_X509_PUBKEY(NULL, &q, length); if (!xpk) return NULL; pktmp = X509_PUBKEY_get(xpk); X509_PUBKEY_free(xpk); if (!pktmp) return NULL; *pp = q; if (a) { EVP_PKEY_free(*a); *a = pktmp; } return pktmp; }
EVP_PKEY * cga_der2key(uint8_t *dk, int klen) { EVP_PKEY *k; X509_PUBKEY *xpk; if ((xpk = d2i_X509_PUBKEY(NULL, #if OPENSSL_VERSION_NUMBER >= 0x0090800fL (const unsigned char **) #endif &dk, klen)) == NULL) { applog(LOG_ERR, "%s: d2i failed", __FUNCTION__); return (NULL); } k = X509_PUBKEY_get(xpk); X509_PUBKEY_free(xpk); return (k); }
OP_STATUS CryptoSignature_impl::SetPublicKey(const UINT8* public_key, int key_length) { if (!public_key || key_length <= 0) return OpStatus::ERR_OUT_OF_RANGE; // This function supports public keys in different formats, such as // X509_PUBKEY and EVP_PKEY-with-RSA-key-only objects. // It should be made more generic, simple and straightforward: // only EVP_PKEY objects should be supported. // This function tries to decode data at "public_key" pointer as X509_PUBKEY, // if fails - as EVP_PKEY_RSA. // Clear the existing key, if any. if (m_keyspec) { EVP_PKEY_free(m_keyspec); m_keyspec = NULL; } // Try hypothesis: public key is X509_PUBKEY. // Temporary variable as recommended by "man d2i_X509". const unsigned char* public_key_tmp = public_key; // Construct X509_PUBKEY object. We own it. X509_PUBKEY* pubkey = d2i_X509_PUBKEY(NULL, &public_key_tmp, key_length); if (pubkey) { m_keyspec = X509_PUBKEY_get(pubkey); // X509_PUBKEY_get allocates new EVP_PKEY, so it's safe // to deallocate pubkey now. X509_PUBKEY_free(pubkey); } ERR_clear_error(); // Try hypothesis: public key is EVP_PKEY_RSA. if (m_keyspec == NULL) { switch (m_cipher_algorithm ) { case CRYPTO_CIPHER_TYPE_RSA: // Temporary variable my have changed its value, resetting. public_key_tmp = public_key; m_keyspec = d2i_PublicKey(EVP_PKEY_RSA, NULL, &public_key_tmp, key_length); ERR_clear_error(); break; default: return OpStatus::ERR_NOT_SUPPORTED; } } if (m_keyspec) return OpStatus::OK; return OpStatus::ERR; }