blob: ce3fce3428e8c7a2f9f99e12a0cd4a09c549a6a1 [file] [log] [blame]
/* BEGIN_HEADER */
#include "mbedtls/bignum.h"
#include "mbedtls/x509_crt.h"
#include "mbedtls/x509_csr.h"
#include "mbedtls/pem.h"
#include "mbedtls/oid.h"
#include "mbedtls/rsa.h"
#if defined(MBEDTLS_RSA_C)
int mbedtls_rsa_decrypt_func(void *ctx,
size_t *olen,
const unsigned char *input,
unsigned char *output,
size_t output_max_len)
{
return (mbedtls_rsa_pkcs1_decrypt((mbedtls_rsa_context *)ctx, NULL, NULL,
olen, input, output, output_max_len));
}
int mbedtls_rsa_sign_func(void *ctx,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng,
mbedtls_md_type_t md_alg,
unsigned int hashlen,
const unsigned char *hash,
unsigned char *sig)
{
return (mbedtls_rsa_pkcs1_sign((mbedtls_rsa_context *)ctx, f_rng, p_rng,
md_alg, hashlen, hash, sig));
}
size_t mbedtls_rsa_key_len_func(void *ctx)
{
return ((const mbedtls_rsa_context *)ctx)->len;
}
#endif /* MBEDTLS_RSA_C */
#if defined(MBEDTLS_USE_PSA_CRYPTO) && defined(MBEDTLS_PEM_WRITE_C) && \
defined(MBEDTLS_X509_CSR_WRITE_C)
static int x509_crt_verifycsr(const unsigned char *buf, size_t buflen)
{
unsigned char hash[MBEDTLS_MD_MAX_SIZE];
const mbedtls_md_info_t *md_info;
mbedtls_x509_csr csr;
int ret = 0;
mbedtls_x509_csr_init(&csr);
if (mbedtls_x509_csr_parse(&csr, buf, buflen) != 0) {
ret = MBEDTLS_ERR_X509_BAD_INPUT_DATA;
goto cleanup;
}
md_info = mbedtls_md_info_from_type(csr.sig_md);
if (mbedtls_md(md_info, csr.cri.p, csr.cri.len, hash) != 0) {
/* Note: this can't happen except after an internal error */
ret = MBEDTLS_ERR_X509_BAD_INPUT_DATA;
goto cleanup;
}
if (mbedtls_pk_verify_ext(csr.sig_pk, csr.sig_opts, &csr.pk, csr.sig_md,
hash, mbedtls_md_get_size(md_info), csr.sig.p,
csr.sig.len) != 0) {
ret = MBEDTLS_ERR_X509_CERT_VERIFY_FAILED;
goto cleanup;
}
cleanup:
mbedtls_x509_csr_free(&csr);
return ret;
}
#endif /* MBEDTLS_USE_PSA_CRYPTO && MBEDTLS_PEM_WRITE_C && \
MBEDTLS_X509_CSR_WRITE_C */
/* END_HEADER */
/* BEGIN_DEPENDENCIES
* depends_on:MBEDTLS_BIGNUM_C:MBEDTLS_FS_IO:MBEDTLS_PK_PARSE_C
* END_DEPENDENCIES
*/
/* BEGIN_CASE depends_on:MBEDTLS_PEM_WRITE_C:MBEDTLS_X509_CSR_WRITE_C */
void x509_csr_check(char *key_file,
char *cert_req_check_file,
int md_type,
int key_usage,
int set_key_usage,
int cert_type,
int set_cert_type)
{
mbedtls_pk_context key;
mbedtls_x509write_csr req;
unsigned char buf[4096];
unsigned char check_buf[4000];
int ret;
size_t olen = 0, pem_len = 0, buf_index;
int der_len = -1;
FILE *f;
const char *subject_name = "C=NL,O=PolarSSL,CN=PolarSSL Server 1";
mbedtls_test_rnd_pseudo_info rnd_info;
memset(&rnd_info, 0x2a, sizeof(mbedtls_test_rnd_pseudo_info));
mbedtls_pk_init(&key);
TEST_ASSERT(mbedtls_pk_parse_keyfile(&key, key_file, NULL,
mbedtls_test_rnd_std_rand, NULL) == 0);
mbedtls_x509write_csr_init(&req);
mbedtls_x509write_csr_set_md_alg(&req, md_type);
mbedtls_x509write_csr_set_key(&req, &key);
TEST_ASSERT(mbedtls_x509write_csr_set_subject_name(&req, subject_name) ==
0);
if (set_key_usage != 0)
TEST_ASSERT(mbedtls_x509write_csr_set_key_usage(&req, key_usage) == 0);
if (set_cert_type != 0)
TEST_ASSERT(mbedtls_x509write_csr_set_ns_cert_type(&req, cert_type) ==
0);
ret = mbedtls_x509write_csr_pem(&req, buf, sizeof(buf),
mbedtls_test_rnd_pseudo_rand, &rnd_info);
TEST_ASSERT(ret == 0);
pem_len = strlen((char *)buf);
for (buf_index = pem_len; buf_index < sizeof(buf); ++buf_index) {
TEST_ASSERT(buf[buf_index] == 0);
}
f = fopen(cert_req_check_file, "r");
TEST_ASSERT(f != NULL);
olen = fread(check_buf, 1, sizeof(check_buf), f);
fclose(f);
TEST_ASSERT(olen >= pem_len - 1);
TEST_ASSERT(memcmp(buf, check_buf, pem_len - 1) == 0);
der_len = mbedtls_x509write_csr_der(
&req, buf, sizeof(buf), mbedtls_test_rnd_pseudo_rand, &rnd_info);
TEST_ASSERT(der_len >= 0);
if (der_len == 0)
goto exit;
ret = mbedtls_x509write_csr_der(&req, buf, (size_t)(der_len - 1),
mbedtls_test_rnd_pseudo_rand, &rnd_info);
TEST_ASSERT(ret == MBEDTLS_ERR_ASN1_BUF_TOO_SMALL);
exit:
mbedtls_x509write_csr_free(&req);
mbedtls_pk_free(&key);
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_PEM_WRITE_C:MBEDTLS_X509_CSR_WRITE_C:MBEDTLS_USE_PSA_CRYPTO */
void x509_csr_check_opaque(char *key_file,
int md_type,
int key_usage,
int cert_type)
{
mbedtls_pk_context key;
mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT;
psa_algorithm_t md_alg_psa;
mbedtls_x509write_csr req;
unsigned char buf[4096];
int ret;
size_t pem_len = 0;
const char *subject_name = "C=NL,O=PolarSSL,CN=PolarSSL Server 1";
mbedtls_test_rnd_pseudo_info rnd_info;
PSA_INIT();
memset(&rnd_info, 0x2a, sizeof(mbedtls_test_rnd_pseudo_info));
md_alg_psa = mbedtls_psa_translate_md((mbedtls_md_type_t)md_type);
TEST_ASSERT(md_alg_psa != MBEDTLS_MD_NONE);
mbedtls_pk_init(&key);
TEST_ASSERT(mbedtls_pk_parse_keyfile(&key, key_file, NULL,
mbedtls_test_rnd_std_rand, NULL) == 0);
TEST_ASSERT(mbedtls_pk_wrap_as_opaque(&key, &key_id, md_alg_psa) == 0);
mbedtls_x509write_csr_init(&req);
mbedtls_x509write_csr_set_md_alg(&req, md_type);
mbedtls_x509write_csr_set_key(&req, &key);
TEST_ASSERT(mbedtls_x509write_csr_set_subject_name(&req, subject_name) ==
0);
if (key_usage != 0)
TEST_ASSERT(mbedtls_x509write_csr_set_key_usage(&req, key_usage) == 0);
if (cert_type != 0)
TEST_ASSERT(mbedtls_x509write_csr_set_ns_cert_type(&req, cert_type) ==
0);
ret = mbedtls_x509write_csr_pem(&req, buf, sizeof(buf) - 1,
mbedtls_test_rnd_pseudo_rand, &rnd_info);
TEST_ASSERT(ret == 0);
pem_len = strlen((char *)buf);
buf[pem_len] = '\0';
TEST_ASSERT(x509_crt_verifycsr(buf, pem_len + 1) == 0);
exit:
mbedtls_x509write_csr_free(&req);
mbedtls_pk_free(&key);
psa_destroy_key(key_id);
PSA_DONE();
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_PEM_WRITE_C:MBEDTLS_X509_CRT_WRITE_C:MBEDTLS_SHA1_C */
void x509_crt_check(char *subject_key_file,
char *subject_pwd,
char *subject_name,
char *issuer_key_file,
char *issuer_pwd,
char *issuer_name,
char *serial_str,
char *not_before,
char *not_after,
int md_type,
int key_usage,
int set_key_usage,
int cert_type,
int set_cert_type,
int auth_ident,
int ver,
char *cert_check_file,
int rsa_alt,
int is_ca)
{
mbedtls_pk_context subject_key, issuer_key, issuer_key_alt;
mbedtls_pk_context *key = &issuer_key;
mbedtls_x509write_cert crt;
unsigned char buf[4096];
unsigned char check_buf[5000];
mbedtls_mpi serial;
int ret;
size_t olen = 0, pem_len = 0, buf_index = 0;
int der_len = -1;
FILE *f;
mbedtls_test_rnd_pseudo_info rnd_info;
memset(&rnd_info, 0x2a, sizeof(mbedtls_test_rnd_pseudo_info));
mbedtls_mpi_init(&serial);
mbedtls_pk_init(&subject_key);
mbedtls_pk_init(&issuer_key);
mbedtls_pk_init(&issuer_key_alt);
mbedtls_x509write_crt_init(&crt);
TEST_ASSERT(mbedtls_pk_parse_keyfile(&subject_key, subject_key_file,
subject_pwd, mbedtls_test_rnd_std_rand,
NULL) == 0);
TEST_ASSERT(mbedtls_pk_parse_keyfile(&issuer_key, issuer_key_file,
issuer_pwd, mbedtls_test_rnd_std_rand,
NULL) == 0);
#if defined(MBEDTLS_RSA_C)
/* For RSA PK contexts, create a copy as an alternative RSA context. */
if (rsa_alt == 1 && mbedtls_pk_get_type(&issuer_key) == MBEDTLS_PK_RSA) {
TEST_ASSERT(mbedtls_pk_setup_rsa_alt(
&issuer_key_alt, mbedtls_pk_rsa(issuer_key),
mbedtls_rsa_decrypt_func, mbedtls_rsa_sign_func,
mbedtls_rsa_key_len_func) == 0);
key = &issuer_key_alt;
}
#else
(void)rsa_alt;
#endif
TEST_ASSERT(mbedtls_test_read_mpi(&serial, 10, serial_str) == 0);
if (ver != -1)
mbedtls_x509write_crt_set_version(&crt, ver);
TEST_ASSERT(mbedtls_x509write_crt_set_serial(&crt, &serial) == 0);
TEST_ASSERT(
mbedtls_x509write_crt_set_validity(&crt, not_before, not_after) == 0);
mbedtls_x509write_crt_set_md_alg(&crt, md_type);
TEST_ASSERT(mbedtls_x509write_crt_set_issuer_name(&crt, issuer_name) == 0);
TEST_ASSERT(mbedtls_x509write_crt_set_subject_name(&crt, subject_name) ==
0);
mbedtls_x509write_crt_set_subject_key(&crt, &subject_key);
mbedtls_x509write_crt_set_issuer_key(&crt, key);
if (crt.version >= MBEDTLS_X509_CRT_VERSION_3) {
/* For the CA case, a path length of -1 means unlimited. */
TEST_ASSERT(mbedtls_x509write_crt_set_basic_constraints(
&crt, is_ca, (is_ca ? -1 : 0)) == 0);
TEST_ASSERT(mbedtls_x509write_crt_set_subject_key_identifier(&crt) ==
0);
if (auth_ident)
TEST_ASSERT(
mbedtls_x509write_crt_set_authority_key_identifier(&crt) == 0);
if (set_key_usage != 0)
TEST_ASSERT(mbedtls_x509write_crt_set_key_usage(&crt, key_usage) ==
0);
if (set_cert_type != 0)
TEST_ASSERT(
mbedtls_x509write_crt_set_ns_cert_type(&crt, cert_type) == 0);
}
ret = mbedtls_x509write_crt_pem(&crt, buf, sizeof(buf),
mbedtls_test_rnd_pseudo_rand, &rnd_info);
TEST_ASSERT(ret == 0);
pem_len = strlen((char *)buf);
// check that the rest of the buffer remains clear
for (buf_index = pem_len; buf_index < sizeof(buf); ++buf_index) {
TEST_ASSERT(buf[buf_index] == 0);
}
f = fopen(cert_check_file, "r");
TEST_ASSERT(f != NULL);
olen = fread(check_buf, 1, sizeof(check_buf), f);
fclose(f);
TEST_ASSERT(olen < sizeof(check_buf));
TEST_ASSERT(olen >= pem_len - 1);
TEST_ASSERT(memcmp(buf, check_buf, pem_len - 1) == 0);
der_len = mbedtls_x509write_crt_der(
&crt, buf, sizeof(buf), mbedtls_test_rnd_pseudo_rand, &rnd_info);
TEST_ASSERT(der_len >= 0);
if (der_len == 0)
goto exit;
ret = mbedtls_x509write_crt_der(&crt, buf, (size_t)(der_len - 1),
mbedtls_test_rnd_pseudo_rand, &rnd_info);
TEST_ASSERT(ret == MBEDTLS_ERR_ASN1_BUF_TOO_SMALL);
exit:
mbedtls_x509write_crt_free(&crt);
mbedtls_pk_free(&issuer_key_alt);
mbedtls_pk_free(&subject_key);
mbedtls_pk_free(&issuer_key);
mbedtls_mpi_free(&serial);
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_X509_CREATE_C:MBEDTLS_X509_USE_C */
void mbedtls_x509_string_to_names(char *name, char *parsed_name, int result)
{
int ret;
size_t len = 0;
mbedtls_asn1_named_data *names = NULL;
mbedtls_x509_name parsed, *parsed_cur, *parsed_prv;
unsigned char buf[1024], out[1024], *c;
memset(&parsed, 0, sizeof(parsed));
memset(out, 0, sizeof(out));
memset(buf, 0, sizeof(buf));
c = buf + sizeof(buf);
ret = mbedtls_x509_string_to_names(&names, name);
TEST_ASSERT(ret == result);
if (ret != 0)
goto exit;
ret = mbedtls_x509_write_names(&c, buf, names);
TEST_ASSERT(ret > 0);
TEST_ASSERT(mbedtls_asn1_get_tag(&c, buf + sizeof(buf), &len,
MBEDTLS_ASN1_CONSTRUCTED |
MBEDTLS_ASN1_SEQUENCE) == 0);
TEST_ASSERT(mbedtls_x509_get_name(&c, buf + sizeof(buf), &parsed) == 0);
ret = mbedtls_x509_dn_gets((char *)out, sizeof(out), &parsed);
TEST_ASSERT(ret > 0);
TEST_ASSERT(strcmp((char *)out, parsed_name) == 0);
exit:
mbedtls_asn1_free_named_data_list(&names);
parsed_cur = parsed.next;
while (parsed_cur != 0) {
parsed_prv = parsed_cur;
parsed_cur = parsed_cur->next;
mbedtls_free(parsed_prv);
}
}
/* END_CASE */