Skip to content

Commit

Permalink
Merge pull request #22 from thalman/disable-rsa-pkcs1.5
Browse files Browse the repository at this point in the history
Make RSA PKCS 1 optional
  • Loading branch information
zandbelt authored Apr 23, 2024
2 parents 27d2d5d + 251c132 commit 721b630
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 3 deletions.
14 changes: 14 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,20 @@ AC_CHECK_LIB([jansson],
[AC_MSG_ERROR([Jansson is missing; it is required for this software])]
)

#### Allow risky rsa pkcs 1.5 for systems where this is really needed
AC_MSG_CHECKING([for RSA PKCS v1.5])
AC_ARG_WITH(
[rsapkcs1_5],
[AS_HELP_STRING([--with-rsapkcs1_5], [Enable risky RSA PKCS v1.5])],
[rsapkcs1_5=${withval}],
[rsapkcs1_5=no])

AC_MSG_RESULT([$rsapkcs1_5])

if test "x$rsapkcs1_5" == xyes ; then
AC_DEFINE(HAVE_RSA_PKCS1_PADDING, 1)
fi

AM_EXTRA_RECURSIVE_TARGETS([package])
AC_CONFIG_FILES([Makefile
include/Makefile include/cjose/version.h
Expand Down
24 changes: 24 additions & 0 deletions src/jwe.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,11 @@ _cjose_jwe_encrypt_ek_rsa_oaep(_jwe_int_recipient_t *recipient, cjose_jwe_t *jwe
static bool
_cjose_jwe_decrypt_ek_rsa_oaep(_jwe_int_recipient_t *recipient, cjose_jwe_t *jwe, const cjose_jwk_t *jwk, cjose_err *err);

#ifdef HAVE_RSA_PKCS1_PADDING
static bool _cjose_jwe_encrypt_ek_rsa1_5(_jwe_int_recipient_t *recipient, cjose_jwe_t *jwe, const cjose_jwk_t *jwk, cjose_err *err);

static bool _cjose_jwe_decrypt_ek_rsa1_5(_jwe_int_recipient_t *recipient, cjose_jwe_t *jwe, const cjose_jwk_t *jwk, cjose_err *err);
#endif // HAVE_RSA_PKCS1_PADDING

static bool
_cjose_jwe_encrypt_ek_ecdh_es(_jwe_int_recipient_t *recipient, cjose_jwe_t *jwe, const cjose_jwk_t *jwk, cjose_err *err);
Expand Down Expand Up @@ -327,11 +329,14 @@ static bool _cjose_jwe_validate_alg(cjose_header_t *protected_header,
recipient->fns.encrypt_ek = _cjose_jwe_encrypt_ek_rsa_oaep;
recipient->fns.decrypt_ek = _cjose_jwe_decrypt_ek_rsa_oaep;
}

#ifdef HAVE_RSA_PKCS1_PADDING
if (strcmp(alg, CJOSE_HDR_ALG_RSA1_5) == 0)
{
recipient->fns.encrypt_ek = _cjose_jwe_encrypt_ek_rsa1_5;
recipient->fns.decrypt_ek = _cjose_jwe_decrypt_ek_rsa1_5;
}
#endif // HAVE_RSA_PKCS1_PADDING
if (strcmp(alg, CJOSE_HDR_ALG_ECDH_ES) == 0)
{
if (is_multiple)
Expand Down Expand Up @@ -642,6 +647,14 @@ static bool _cjose_jwe_encrypt_ek_rsa_padding(
return false;
}

#ifndef HAVE_RSA_PKCS1_PADDING
// prohibite RSA_PKCS1_PADDING because it is not safe
if (padding == RSA_PKCS1_PADDING) {
CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
return false;
}
#endif // HAVE_RSA_PKCS1_PADDING

// encrypt the CEK using RSA v1.5 or OAEP padding
if (RSA_public_encrypt(jwe->cek_len, jwe->cek, recipient->enc_key.raw, (RSA *)jwk->keydata, padding)
!= recipient->enc_key.raw_len)
Expand Down Expand Up @@ -687,6 +700,15 @@ static bool _cjose_jwe_decrypt_ek_rsa_padding(
return false;
}

#ifndef HAVE_RSA_PKCS1_PADDING
// prohibite RSA_PKCS1_PADDING because implementation are often vulnerable
// See marvin attack
if (padding == RSA_PKCS1_PADDING) {
CJOSE_ERROR(err, CJOSE_ERR_CRYPTO);
return false;
}
#endif // HAVE_RSA_PKCS1_PADDING

// decrypt the CEK using RSA v1.5 or OAEP padding
int len = RSA_private_decrypt(recipient->enc_key.raw_len, recipient->enc_key.raw, jwe->cek, (RSA *)jwk->keydata, padding);
if (-1 == len)
Expand Down Expand Up @@ -714,6 +736,7 @@ _cjose_jwe_decrypt_ek_rsa_oaep(_jwe_int_recipient_t *recipient, cjose_jwe_t *jwe
return _cjose_jwe_decrypt_ek_rsa_padding(recipient, jwe, jwk, RSA_PKCS1_OAEP_PADDING, err);
}

#ifdef HAVE_RSA_PKCS1_PADDING
////////////////////////////////////////////////////////////////////////////////
static bool _cjose_jwe_encrypt_ek_rsa1_5(_jwe_int_recipient_t *recipient, cjose_jwe_t *jwe, const cjose_jwk_t *jwk, cjose_err *err)
{
Expand All @@ -725,6 +748,7 @@ static bool _cjose_jwe_decrypt_ek_rsa1_5(_jwe_int_recipient_t *recipient, cjose_
{
return _cjose_jwe_decrypt_ek_rsa_padding(recipient, jwe, jwk, RSA_PKCS1_PADDING, err);
}
#endif // HAVE_RSA_PKCS1_PADDING

////////////////////////////////////////////////////////////////////////////////
static bool _cjose_jwe_encrypt_ek_ecdh_es(_jwe_int_recipient_t *recipient, cjose_jwe_t *jwe, const cjose_jwk_t *jwk, cjose_err *err)
Expand Down
18 changes: 15 additions & 3 deletions test/check_jwe.c
Original file line number Diff line number Diff line change
Expand Up @@ -210,19 +210,25 @@ static void _self_encrypt_self_decrypt(const char *plain1)
{
_self_encrypt_self_decrypt_with_key(CJOSE_HDR_ALG_RSA_OAEP, CJOSE_HDR_ENC_A128GCM, JWK_RSA, plain1);

#ifdef HAVE_RSA_PKCS1_PADDING
_self_encrypt_self_decrypt_with_key(CJOSE_HDR_ALG_RSA1_5, CJOSE_HDR_ENC_A128GCM, JWK_RSA, plain1);

#endif

_self_encrypt_self_decrypt_with_key(CJOSE_HDR_ALG_DIR, CJOSE_HDR_ENC_A128GCM, JWK_OCT_16, plain1);

_self_encrypt_self_decrypt_with_key(CJOSE_HDR_ALG_RSA_OAEP, CJOSE_HDR_ENC_A192GCM, JWK_RSA, plain1);

#ifdef HAVE_RSA_PKCS1_PADDING
_self_encrypt_self_decrypt_with_key(CJOSE_HDR_ALG_RSA1_5, CJOSE_HDR_ENC_A192GCM, JWK_RSA, plain1);
#endif

_self_encrypt_self_decrypt_with_key(CJOSE_HDR_ALG_DIR, CJOSE_HDR_ENC_A192GCM, JWK_OCT_24, plain1);

_self_encrypt_self_decrypt_with_key(CJOSE_HDR_ALG_RSA_OAEP, CJOSE_HDR_ENC_A256GCM, JWK_RSA, plain1);

#ifdef HAVE_RSA_PKCS1_PADDING
_self_encrypt_self_decrypt_with_key(CJOSE_HDR_ALG_RSA1_5, CJOSE_HDR_ENC_A256GCM, JWK_RSA, plain1);
#endif

_self_encrypt_self_decrypt_with_key(CJOSE_HDR_ALG_DIR, CJOSE_HDR_ENC_A256GCM, JWK_OCT_32, plain1);

Expand Down Expand Up @@ -358,8 +364,10 @@ static void _self_encrypt_self_decrypt_iv(const char *plain1)

_self_encrypt_self_decrypt_with_key_iv(CJOSE_HDR_ALG_RSA_OAEP, CJOSE_HDR_ENC_A256GCM, JWK_RSA, 12, plain1);

#ifdef HAVE_RSA_PKCS1_PADDING
_self_encrypt_self_decrypt_with_key_iv(CJOSE_HDR_ALG_RSA1_5, CJOSE_HDR_ENC_A256GCM, JWK_RSA, 12, plain1);

#endif

_self_encrypt_self_decrypt_with_key_iv(CJOSE_HDR_ALG_DIR, CJOSE_HDR_ENC_A256GCM, JWK_OCT_32, 12, plain1);

_self_encrypt_self_decrypt_with_key_iv(CJOSE_HDR_ALG_DIR, CJOSE_HDR_ENC_A128CBC_HS256, JWK_OCT_32, 16, plain1);
Expand Down Expand Up @@ -1081,6 +1089,7 @@ START_TEST(test_cjose_jwe_decrypt_rsa)
"AlWAyLWybqq6t16VFd7hQd0y6flUK4SlOydB61gwanOsXGOAOv82cHq0E3"
"eL4HrtZkUuKvnPrMnsUUFlfUdybVzxyjz9JF_XyaY14ardLSjf4L_FNY\" }" },

#ifdef HAVE_RSA_PKCS1_PADDING
// https://tools.ietf.org/html/rfc7516#appendix-A.2
// JWE using RSAES-PKCS1-v1_5 and AES_128_CBC_HMAC_SHA_256
{ "eyJhbGciOiJSU0ExXzUiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0."
Expand Down Expand Up @@ -1125,7 +1134,8 @@ START_TEST(test_cjose_jwe_decrypt_rsa)
"\"qi\":\"eNho5yRBEBxhGBtQRww9QirZsB66TrfFReG_CcteI1aCneT0ELGhYlRlC"
"tUkTRclIfuEPmNsNDPbLoLqqCVznFbvdB7x-Tl-m0l_eFTj2KiqwGqE9PZ"
"B9nNTwMVvH3VRRSLWACvPnSiwP8N5Usy-WRXS-V7TbpxIhvepTfE0NNo\" }" },

#endif // HAVE_RSA_PKCS1_PADDING

{ NULL, NULL, NULL }
};

Expand Down Expand Up @@ -1257,6 +1267,7 @@ static void _cjose_test_empty_headers(cjose_jwk_t *key)
START_TEST(test_cjose_jwe_multiple_recipients)
{

#ifdef HAVE_RSA_PKCS1_PADDING
char *rsa[] = { "{\"kty\":\"RSA\",\"e\":\"AQAB\",\"n\":\"pXldOFJS1PKXlkkkcCKtBt6efl84jkZinEzVF1HcksvO_b"
"QUFJbUPcZwyzKk8fYnGbu0LwnY3hhCSDk-Ki8S2h_8VOiR7AY2ptI_TjeGp0DDqSnmJEdDrwIbw0yGTgOHZ63xms0aE4"
"fv9tdrw5U4v_A3AfOwUtCyxuyZP_7WlNj0sMsWwiyp0BGvCUB4xuhVtsEsbSWvSAO8CYHEy3fVGZ6bLXh7DbF7WlbfZ9K"
Expand Down Expand Up @@ -1413,6 +1424,7 @@ START_TEST(test_cjose_jwe_multiple_recipients)
}

cjose_header_release(protected_header);
#endif // HAVE_RSA_PKCS1_PADDING
}
END_TEST

Expand Down

0 comments on commit 721b630

Please sign in to comment.