quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

test_suite_pkparse.function (10733B)


      1 /* BEGIN_HEADER */
      2 #include "mbedtls/pk.h"
      3 #include "mbedtls/pem.h"
      4 #include "mbedtls/oid.h"
      5 #include "mbedtls/ecp.h"
      6 #include "mbedtls/psa_util.h"
      7 #include "pk_internal.h"
      8 
      9 #if defined(MBEDTLS_PSA_CRYPTO_C)
     10 #include "test/psa_exercise_key.h"
     11 #endif
     12 
     13 #if defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C)
     14 #define HAVE_mbedtls_pk_parse_key_pkcs8_encrypted_der
     15 #endif
     16 
     17 #if defined(MBEDTLS_PSA_CRYPTO_C) && defined(MBEDTLS_FS_IO)
     18 static int test_psa_bridge(const mbedtls_pk_context *ctx,
     19                            psa_key_usage_t usage_flag)
     20 {
     21     switch (usage_flag) {
     22         case PSA_KEY_USAGE_SIGN_HASH:
     23             mbedtls_test_set_step(0);
     24             break;
     25         case PSA_KEY_USAGE_SIGN_MESSAGE:
     26             mbedtls_test_set_step(1);
     27             break;
     28         case PSA_KEY_USAGE_DECRYPT:
     29             mbedtls_test_set_step(2);
     30             break;
     31         case PSA_KEY_USAGE_DERIVE:
     32             mbedtls_test_set_step(3);
     33             break;
     34         case PSA_KEY_USAGE_VERIFY_HASH:
     35             mbedtls_test_set_step(4);
     36             break;
     37         case PSA_KEY_USAGE_VERIFY_MESSAGE:
     38             mbedtls_test_set_step(5);
     39             break;
     40         case PSA_KEY_USAGE_ENCRYPT:
     41             mbedtls_test_set_step(6);
     42             break;
     43     }
     44 
     45     psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
     46     mbedtls_svc_key_id_t psa_key = MBEDTLS_SVC_KEY_ID_INIT;
     47     int ok = 0;
     48 
     49     TEST_EQUAL(mbedtls_pk_get_psa_attributes(ctx, usage_flag, &attributes), 0);
     50     int ret = mbedtls_pk_import_into_psa(ctx, &attributes, &psa_key);
     51     if (mbedtls_pk_get_type(ctx) == MBEDTLS_PK_RSA &&
     52         mbedtls_pk_get_bitlen(ctx) % 8 != 0 &&
     53         ret == MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE) {
     54         /* There is a historical limitation with support for RSA keys in PSA:
     55          * only byte-aligned sizes are supported.
     56          * https://github.com/Mbed-TLS/mbedtls/issues/9048
     57          * For now, for such keys, treat not-supported from PSA as a success.
     58          */
     59         ok = 1;
     60         goto exit;
     61     }
     62     TEST_EQUAL(ret, 0);
     63     if (!mbedtls_test_key_consistency_psa_pk(psa_key, ctx)) {
     64         goto exit;
     65     }
     66 
     67     psa_algorithm_t exercise_usage = psa_get_key_usage_flags(&attributes);
     68     psa_algorithm_t exercise_alg = psa_get_key_algorithm(&attributes);
     69     if (mbedtls_test_can_exercise_psa_algorithm(exercise_alg)) {
     70         TEST_ASSERT(mbedtls_test_psa_exercise_key(psa_key,
     71                                                   exercise_usage,
     72                                                   exercise_alg, 0));
     73     }
     74 
     75     mbedtls_test_set_step((unsigned long) -1);
     76     ok = 1;
     77 
     78 exit:
     79     psa_destroy_key(psa_key);
     80     psa_reset_key_attributes(&attributes);
     81     return ok;
     82 }
     83 
     84 #if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
     85 /* Whether a pk key can do ECDSA. Opaque keys are not supported since this
     86  * test suite does not create opaque keys. */
     87 static int pk_can_ecdsa(const mbedtls_pk_context *ctx)
     88 {
     89     /* Check whether we have an EC key. Unfortunately this also accepts
     90      * keys on Montgomery curves, which can only do ECDH, so we'll have
     91      * to dig further. */
     92     if (!mbedtls_pk_can_do(ctx, MBEDTLS_PK_ECDSA)) {
     93         return 0;
     94     }
     95 #if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
     96     return ctx->ec_family != PSA_ECC_FAMILY_MONTGOMERY;
     97 #elif defined(MBEDTLS_ECDSA_C)
     98     return mbedtls_ecdsa_can_do(mbedtls_pk_ec_ro(*ctx)->grp.id);
     99 #else
    100     return 0;
    101 #endif
    102 }
    103 #endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
    104 #endif /* MBEDTLS_PSA_CRYPTO_C &&  && MBEDTLS_FS_IO */
    105 
    106 /* END_HEADER */
    107 
    108 /* BEGIN_DEPENDENCIES
    109  * depends_on:MBEDTLS_PK_PARSE_C
    110  * END_DEPENDENCIES
    111  */
    112 
    113 /* BEGIN_CASE depends_on:MBEDTLS_RSA_C:MBEDTLS_FS_IO */
    114 void pk_parse_keyfile_rsa(char *key_file, char *password, int result)
    115 {
    116     mbedtls_pk_context ctx;
    117     mbedtls_pk_init(&ctx);
    118     int res;
    119     char *pwd = password;
    120 
    121     MD_PSA_INIT();
    122 
    123     if (strcmp(pwd, "NULL") == 0) {
    124         pwd = NULL;
    125     }
    126 
    127     res = mbedtls_pk_parse_keyfile(&ctx, key_file, pwd,
    128                                    mbedtls_test_rnd_std_rand, NULL);
    129 
    130     TEST_EQUAL(res, result);
    131 
    132     if (res == 0) {
    133         mbedtls_rsa_context *rsa;
    134         TEST_ASSERT(mbedtls_pk_can_do(&ctx, MBEDTLS_PK_RSA));
    135         rsa = mbedtls_pk_rsa(ctx);
    136         TEST_EQUAL(mbedtls_rsa_check_privkey(rsa), 0);
    137 
    138         size_t bitlen = mbedtls_rsa_get_bitlen(rsa);
    139         TEST_EQUAL(mbedtls_pk_get_bitlen(&ctx), bitlen);
    140         TEST_EQUAL(mbedtls_pk_get_len(&ctx), (bitlen + 7) / 8);
    141 
    142 #if defined(MBEDTLS_PSA_CRYPTO_C)
    143         PSA_INIT();
    144         TEST_ASSERT(test_psa_bridge(&ctx, PSA_KEY_USAGE_SIGN_HASH));
    145         TEST_ASSERT(test_psa_bridge(&ctx, PSA_KEY_USAGE_SIGN_MESSAGE));
    146         TEST_ASSERT(test_psa_bridge(&ctx, PSA_KEY_USAGE_DECRYPT));
    147         TEST_ASSERT(test_psa_bridge(&ctx, PSA_KEY_USAGE_VERIFY_HASH));
    148         TEST_ASSERT(test_psa_bridge(&ctx, PSA_KEY_USAGE_VERIFY_MESSAGE));
    149         TEST_ASSERT(test_psa_bridge(&ctx, PSA_KEY_USAGE_ENCRYPT));
    150 #endif
    151     }
    152 
    153 exit:
    154     mbedtls_pk_free(&ctx);
    155     PSA_DONE();
    156 }
    157 
    158 /* END_CASE */
    159 
    160 /* BEGIN_CASE depends_on:MBEDTLS_RSA_C:MBEDTLS_FS_IO */
    161 void pk_parse_public_keyfile_rsa(char *key_file, int result)
    162 {
    163     mbedtls_pk_context ctx;
    164     mbedtls_pk_init(&ctx);
    165     int res;
    166 
    167     MD_PSA_INIT();
    168 
    169     res = mbedtls_pk_parse_public_keyfile(&ctx, key_file);
    170 
    171     TEST_EQUAL(res, result);
    172 
    173     if (res == 0) {
    174         mbedtls_rsa_context *rsa;
    175         TEST_ASSERT(mbedtls_pk_can_do(&ctx, MBEDTLS_PK_RSA));
    176         rsa = mbedtls_pk_rsa(ctx);
    177         TEST_EQUAL(mbedtls_rsa_check_pubkey(rsa), 0);
    178 
    179         size_t bitlen = mbedtls_rsa_get_bitlen(rsa);
    180         TEST_EQUAL(mbedtls_pk_get_bitlen(&ctx), bitlen);
    181         TEST_EQUAL(mbedtls_pk_get_len(&ctx), (bitlen + 7) / 8);
    182 
    183 #if defined(MBEDTLS_PSA_CRYPTO_C)
    184         PSA_INIT();
    185         TEST_ASSERT(test_psa_bridge(&ctx, PSA_KEY_USAGE_VERIFY_HASH));
    186         TEST_ASSERT(test_psa_bridge(&ctx, PSA_KEY_USAGE_VERIFY_MESSAGE));
    187         TEST_ASSERT(test_psa_bridge(&ctx, PSA_KEY_USAGE_ENCRYPT));
    188 #endif
    189     }
    190 
    191 exit:
    192     mbedtls_pk_free(&ctx);
    193     PSA_DONE();
    194 }
    195 /* END_CASE */
    196 
    197 /* BEGIN_CASE depends_on:MBEDTLS_FS_IO:MBEDTLS_PK_HAVE_ECC_KEYS */
    198 void pk_parse_public_keyfile_ec(char *key_file, int result)
    199 {
    200     mbedtls_pk_context ctx;
    201     int res;
    202 
    203     mbedtls_pk_init(&ctx);
    204     MD_OR_USE_PSA_INIT();
    205 
    206     res = mbedtls_pk_parse_public_keyfile(&ctx, key_file);
    207 
    208     TEST_EQUAL(res, result);
    209 
    210     if (res == 0) {
    211         TEST_ASSERT(mbedtls_pk_can_do(&ctx, MBEDTLS_PK_ECKEY));
    212 #if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
    213         /* No need to check whether the parsed public point is on the curve or
    214          * not because this is already done by the internal "pk_get_ecpubkey()"
    215          * function */
    216 #else
    217         const mbedtls_ecp_keypair *eckey;
    218         eckey = mbedtls_pk_ec_ro(ctx);
    219         TEST_EQUAL(mbedtls_ecp_check_pubkey(&eckey->grp, &eckey->Q), 0);
    220 #endif
    221 
    222 #if defined(MBEDTLS_PSA_CRYPTO_C)
    223         PSA_INIT();
    224         if (pk_can_ecdsa(&ctx)) {
    225             TEST_ASSERT(test_psa_bridge(&ctx, PSA_KEY_USAGE_VERIFY_HASH));
    226             TEST_ASSERT(test_psa_bridge(&ctx, PSA_KEY_USAGE_VERIFY_MESSAGE));
    227         }
    228 #endif
    229     }
    230 
    231 exit:
    232     mbedtls_pk_free(&ctx);
    233     PSA_DONE();
    234 }
    235 /* END_CASE */
    236 
    237 /* BEGIN_CASE depends_on:MBEDTLS_FS_IO:MBEDTLS_PK_HAVE_ECC_KEYS */
    238 void pk_parse_keyfile_ec(char *key_file, char *password, int result)
    239 {
    240     mbedtls_pk_context ctx;
    241     int res;
    242 
    243     mbedtls_pk_init(&ctx);
    244     MD_OR_USE_PSA_INIT();
    245 
    246     res = mbedtls_pk_parse_keyfile(&ctx, key_file, password,
    247                                    mbedtls_test_rnd_std_rand, NULL);
    248 
    249     TEST_EQUAL(res, result);
    250 
    251     if (res == 0) {
    252         TEST_ASSERT(mbedtls_pk_can_do(&ctx, MBEDTLS_PK_ECKEY));
    253 #if defined(MBEDTLS_PK_USE_PSA_EC_DATA)
    254         /* PSA keys are already checked on import so nothing to do here. */
    255 #else
    256         const mbedtls_ecp_keypair *eckey = mbedtls_pk_ec_ro(ctx);
    257         TEST_EQUAL(mbedtls_ecp_check_privkey(&eckey->grp, &eckey->d), 0);
    258 #endif
    259 
    260 #if defined(MBEDTLS_PSA_CRYPTO_C)
    261         PSA_INIT();
    262         TEST_ASSERT(test_psa_bridge(&ctx, PSA_KEY_USAGE_DERIVE));
    263         if (pk_can_ecdsa(&ctx)) {
    264             TEST_ASSERT(test_psa_bridge(&ctx, PSA_KEY_USAGE_SIGN_HASH));
    265             TEST_ASSERT(test_psa_bridge(&ctx, PSA_KEY_USAGE_SIGN_MESSAGE));
    266             TEST_ASSERT(test_psa_bridge(&ctx, PSA_KEY_USAGE_VERIFY_HASH));
    267             TEST_ASSERT(test_psa_bridge(&ctx, PSA_KEY_USAGE_VERIFY_MESSAGE));
    268         }
    269 #endif
    270     }
    271 
    272 exit:
    273     mbedtls_pk_free(&ctx);
    274     PSA_DONE();
    275 }
    276 /* END_CASE */
    277 
    278 /* BEGIN_CASE */
    279 void pk_parse_key(data_t *buf, int result)
    280 {
    281     mbedtls_pk_context pk;
    282 
    283     mbedtls_pk_init(&pk);
    284     USE_PSA_INIT();
    285 
    286     TEST_ASSERT(mbedtls_pk_parse_key(&pk, buf->x, buf->len, NULL, 0,
    287                                      mbedtls_test_rnd_std_rand, NULL) == result);
    288 
    289 exit:
    290     mbedtls_pk_free(&pk);
    291     USE_PSA_DONE();
    292 }
    293 /* END_CASE */
    294 
    295 /* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS:HAVE_mbedtls_pk_parse_key_pkcs8_encrypted_der */
    296 void pk_parse_key_encrypted(data_t *buf, data_t *pass, int result)
    297 {
    298     mbedtls_pk_context pk;
    299 
    300     mbedtls_pk_init(&pk);
    301     USE_PSA_INIT();
    302 
    303     TEST_EQUAL(mbedtls_pk_parse_key_pkcs8_encrypted_der(&pk, buf->x, buf->len,
    304                                                         pass->x, pass->len,
    305                                                         mbedtls_test_rnd_std_rand,
    306                                                         NULL), result);
    307 exit:
    308     mbedtls_pk_free(&pk);
    309     USE_PSA_DONE();
    310 }
    311 /* END_CASE */
    312 
    313 /* BEGIN_CASE depends_on:MBEDTLS_PK_HAVE_ECC_KEYS:MBEDTLS_PK_WRITE_C */
    314 void pk_parse_fix_montgomery(data_t *input_key, data_t *exp_output)
    315 {
    316     /* Montgomery keys have specific bits set to either 0 or 1 depending on
    317      * their position. This is enforced during parsing (please see the implementation
    318      * of mbedtls_ecp_read_key() for more details). The scope of this function
    319      * is to verify this enforcing by feeding the parse algorithm with a x25519
    320      * key which does not have those bits set properly. */
    321     mbedtls_pk_context pk;
    322     unsigned char *output_key = NULL;
    323     size_t output_key_len = 0;
    324 
    325     mbedtls_pk_init(&pk);
    326     USE_PSA_INIT();
    327 
    328     TEST_EQUAL(mbedtls_pk_parse_key(&pk, input_key->x, input_key->len, NULL, 0,
    329                                     mbedtls_test_rnd_std_rand, NULL), 0);
    330 
    331     output_key_len = input_key->len;
    332     TEST_CALLOC(output_key, output_key_len);
    333     /* output_key_len is updated with the real amount of data written to
    334      * output_key buffer. */
    335     output_key_len = mbedtls_pk_write_key_der(&pk, output_key, output_key_len);
    336     TEST_ASSERT(output_key_len > 0);
    337 
    338     TEST_MEMORY_COMPARE(exp_output->x, exp_output->len, output_key, output_key_len);
    339 
    340 exit:
    341     if (output_key != NULL) {
    342         mbedtls_free(output_key);
    343     }
    344     mbedtls_pk_free(&pk);
    345     USE_PSA_DONE();
    346 }
    347 /* END_CASE */