Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Add EVP_PKEY based Decode methods.
  • Loading branch information
bartonjs committed Jun 10, 2021
commit b91a2f8f0d34fefc2d69b4138474aa677626f125
8 changes: 7 additions & 1 deletion .config/dotnet-tools.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@
"commands": [
"slngen"
]
},
"dotnet-sos": {
"version": "5.0.227602",
"commands": [
"dotnet-sos"
]
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,9 @@ static const Entry s_cryptoNative[] =
DllImportEntry(CryptoNative_DecodeExtendedKeyUsage)
DllImportEntry(CryptoNative_DecodeOcspResponse)
DllImportEntry(CryptoNative_DecodePkcs7)
DllImportEntry(CryptoNative_DecodePkcs8PrivateKey)
DllImportEntry(CryptoNative_DecodeRsaPublicKey)
DllImportEntry(CryptoNative_DecodeSubjectPublicKeyInfo)
DllImportEntry(CryptoNative_DecodeX509)
DllImportEntry(CryptoNative_DecodeX509BasicConstraints2Extension)
DllImportEntry(CryptoNative_DecodeX509Crl)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,8 @@ const EVP_CIPHER* EVP_chacha20_poly1305(void);
REQUIRED_FUNCTION(d2i_PKCS12_fp) \
REQUIRED_FUNCTION(d2i_PKCS7) \
REQUIRED_FUNCTION(d2i_PKCS7_bio) \
REQUIRED_FUNCTION(d2i_PKCS8_PRIV_KEY_INFO) \
REQUIRED_FUNCTION(d2i_PUBKEY) \
REQUIRED_FUNCTION(d2i_RSAPublicKey) \
REQUIRED_FUNCTION(d2i_X509) \
REQUIRED_FUNCTION(d2i_X509_bio) \
Expand Down Expand Up @@ -319,6 +321,7 @@ const EVP_CIPHER* EVP_chacha20_poly1305(void);
RENAMED_FUNCTION(EVP_MD_CTX_free, EVP_MD_CTX_destroy) \
RENAMED_FUNCTION(EVP_MD_CTX_new, EVP_MD_CTX_create) \
REQUIRED_FUNCTION(EVP_MD_size) \
REQUIRED_FUNCTION(EVP_PKCS82PKEY) \
REQUIRED_FUNCTION(EVP_PKEY_CTX_ctrl) \
REQUIRED_FUNCTION(EVP_PKEY_CTX_free) \
REQUIRED_FUNCTION(EVP_PKEY_CTX_get0_pkey) \
Expand All @@ -330,6 +333,7 @@ const EVP_CIPHER* EVP_chacha20_poly1305(void);
FALLBACK_FUNCTION(EVP_PKEY_CTX_set_rsa_pss_saltlen) \
FALLBACK_FUNCTION(EVP_PKEY_CTX_set_signature_md) \
REQUIRED_FUNCTION(EVP_PKEY_base_id) \
REQUIRED_FUNCTION(EVP_PKEY_check) \
REQUIRED_FUNCTION(EVP_PKEY_decrypt) \
REQUIRED_FUNCTION(EVP_PKEY_decrypt_init) \
REQUIRED_FUNCTION(EVP_PKEY_derive_set_peer) \
Expand All @@ -345,6 +349,7 @@ const EVP_CIPHER* EVP_chacha20_poly1305(void);
REQUIRED_FUNCTION(EVP_PKEY_keygen) \
REQUIRED_FUNCTION(EVP_PKEY_keygen_init) \
REQUIRED_FUNCTION(EVP_PKEY_new) \
REQUIRED_FUNCTION(EVP_PKEY_public_check) \
REQUIRED_FUNCTION(EVP_PKEY_set1_DSA) \
REQUIRED_FUNCTION(EVP_PKEY_set1_EC_KEY) \
REQUIRED_FUNCTION(EVP_PKEY_set1_RSA) \
Expand Down Expand Up @@ -411,6 +416,7 @@ const EVP_CIPHER* EVP_chacha20_poly1305(void);
RENAMED_FUNCTION(OPENSSL_sk_value, sk_value) \
FALLBACK_FUNCTION(OpenSSL_version_num) \
LIGHTUP_FUNCTION(OSSL_PROVIDER_try_load) \
REQUIRED_FUNCTION(PKCS8_PRIV_KEY_INFO_free) \
REQUIRED_FUNCTION(PEM_read_bio_PKCS7) \
REQUIRED_FUNCTION(PEM_read_bio_X509) \
REQUIRED_FUNCTION(PEM_read_bio_X509_AUX) \
Expand Down Expand Up @@ -638,6 +644,8 @@ FOR_ALL_OPENSSL_FUNCTIONS
#define d2i_PKCS12_fp d2i_PKCS12_fp_ptr
#define d2i_PKCS7 d2i_PKCS7_ptr
#define d2i_PKCS7_bio d2i_PKCS7_bio_ptr
#define d2i_PKCS8_PRIV_KEY_INFO d2i_PKCS8_PRIV_KEY_INFO_ptr
#define d2i_PUBKEY d2i_PUBKEY_ptr
#define d2i_RSAPublicKey d2i_RSAPublicKey_ptr
#define d2i_X509 d2i_X509_ptr
#define d2i_X509_bio d2i_X509_bio_ptr
Expand Down Expand Up @@ -754,6 +762,7 @@ FOR_ALL_OPENSSL_FUNCTIONS
#define EVP_MD_CTX_free EVP_MD_CTX_free_ptr
#define EVP_MD_CTX_new EVP_MD_CTX_new_ptr
#define EVP_MD_size EVP_MD_size_ptr
#define EVP_PKCS82PKEY EVP_PKCS82PKEY_ptr
#define EVP_PKEY_CTX_ctrl EVP_PKEY_CTX_ctrl_ptr
#define EVP_PKEY_CTX_free EVP_PKEY_CTX_free_ptr
#define EVP_PKEY_CTX_get0_pkey EVP_PKEY_CTX_get0_pkey_ptr
Expand All @@ -765,6 +774,7 @@ FOR_ALL_OPENSSL_FUNCTIONS
#define EVP_PKEY_CTX_set_rsa_pss_saltlen EVP_PKEY_CTX_set_rsa_pss_saltlen_ptr
#define EVP_PKEY_CTX_set_signature_md EVP_PKEY_CTX_set_signature_md_ptr
#define EVP_PKEY_base_id EVP_PKEY_base_id_ptr
#define EVP_PKEY_check EVP_PKEY_check_ptr
#define EVP_PKEY_decrypt_init EVP_PKEY_decrypt_init_ptr
#define EVP_PKEY_decrypt EVP_PKEY_decrypt_ptr
#define EVP_PKEY_derive_set_peer EVP_PKEY_derive_set_peer_ptr
Expand All @@ -780,6 +790,7 @@ FOR_ALL_OPENSSL_FUNCTIONS
#define EVP_PKEY_keygen EVP_PKEY_keygen_ptr
#define EVP_PKEY_keygen_init EVP_PKEY_keygen_init_ptr
#define EVP_PKEY_new EVP_PKEY_new_ptr
#define EVP_PKEY_public_check EVP_PKEY_public_check_ptr
#define EVP_PKEY_set1_DSA EVP_PKEY_set1_DSA_ptr
#define EVP_PKEY_set1_EC_KEY EVP_PKEY_set1_EC_KEY_ptr
#define EVP_PKEY_set1_RSA EVP_PKEY_set1_RSA_ptr
Expand Down Expand Up @@ -846,6 +857,7 @@ FOR_ALL_OPENSSL_FUNCTIONS
#define OPENSSL_sk_value OPENSSL_sk_value_ptr
#define OpenSSL_version_num OpenSSL_version_num_ptr
#define OSSL_PROVIDER_try_load OSSL_PROVIDER_try_load_ptr
#define PKCS8_PRIV_KEY_INFO_free PKCS8_PRIV_KEY_INFO_free_ptr
#define PEM_read_bio_PKCS7 PEM_read_bio_PKCS7_ptr
#define PEM_read_bio_X509 PEM_read_bio_X509_ptr
#define PEM_read_bio_X509_AUX PEM_read_bio_X509_AUX_ptr
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,74 @@ int32_t CryptoNative_UpRefEvpPkey(EVP_PKEY* pkey)

return EVP_PKEY_up_ref(pkey);
}

static bool CheckKey(EVP_PKEY* key, int32_t algId, int32_t (*check_func)(EVP_PKEY_CTX*))
{
if (algId != NID_undef && EVP_PKEY_base_id(key) != algId)
{
ERR_put_error(ERR_LIB_EVP, 0, EVP_R_UNSUPPORTED_ALGORITHM, __FILE__, __LINE__);
return false;
}

EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new(key, NULL);

if (ctx == NULL)
{
// The malloc error should have already been set.
return false;
}

int check = check_func(ctx);
EVP_PKEY_CTX_free(ctx);

// 1: Success
// -2: The key object had no check routine available.
if (check == 1 || check == -2)
{
// We need to clear for -2, doesn't hurt for 1.
ERR_clear_error();
return true;
}

return false;
}

EVP_PKEY* CryptoNative_DecodeSubjectPublicKeyInfo(const uint8_t* buf, int32_t len, int32_t algId)
{
assert(buf != NULL);
assert(len > 0);

EVP_PKEY* key = d2i_PUBKEY(NULL, &buf, len);

if (key != NULL && !CheckKey(key, algId, EVP_PKEY_public_check))
{
EVP_PKEY_free(key);
key = NULL;
}

return key;
}

EVP_PKEY* CryptoNative_DecodePkcs8PrivateKey(const uint8_t* buf, int32_t len, int32_t algId)
{
assert(buf != NULL);
assert(len > 0);

PKCS8_PRIV_KEY_INFO* p8info = d2i_PKCS8_PRIV_KEY_INFO(NULL, &buf, len);

if (p8info == NULL)
{
return NULL;
}

EVP_PKEY* key = EVP_PKCS82PKEY(p8info);
PKCS8_PRIV_KEY_INFO_free(p8info);

if (key != NULL && !CheckKey(key, algId, EVP_PKEY_check))
{
EVP_PKEY_free(key);
key = NULL;
}

return key;
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,17 @@ Returns the number (as of this call) of references to the EVP_PKEY. Anything les
2 is an error, because the key is already in the process of being freed.
*/
PALEXPORT int32_t CryptoNative_UpRefEvpPkey(EVP_PKEY* pkey);

/*
* Decodes an X.509 SubjectPublicKeyInfo into an EVP_PKEY*, verifying the interpreted algorithm type.
*
* Requres a non-null buf, and len > 0.
*/
PALEXPORT EVP_PKEY* CryptoNative_DecodeSubjectPublicKeyInfo(const uint8_t* buf, int32_t len, int32_t algId);

/*
* Decodes an Pkcs8PrivateKeyInfo into an EVP_PKEY*, verifying the interpreted algorithm type.
*
* Requres a non-null buf, and len > 0.
*/
PALEXPORT EVP_PKEY* CryptoNative_DecodePkcs8PrivateKey(const uint8_t* buf, int32_t len, int32_t algId);