#include "common.h"
#if defined(MBEDTLS_X509_CRT_PARSE_C)
#include "mbedtls/x509_crt.h"
#include "x509_internal.h"
#include "mbedtls/error.h"
#include "mbedtls/oid.h"
#include "mbedtls/platform_util.h"
#include <string.h>
#if defined(MBEDTLS_PEM_PARSE_C)
#include "mbedtls/pem.h"
#endif
#if defined(MBEDTLS_USE_PSA_CRYPTO)
#include "psa/crypto.h"
#include "psa_util_internal.h"
#include "mbedtls/psa_util.h"
#endif
#include "pk_internal.h"
#include "mbedtls/platform.h"
#if defined(MBEDTLS_THREADING_C)
#include "mbedtls/threading.h"
#endif
#if defined(MBEDTLS_HAVE_TIME)
#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#else
#include <time.h>
#endif
#endif
#if defined(MBEDTLS_FS_IO)
#include <stdio.h>
#if !defined(_WIN32) || defined(EFIX64) || defined(EFI32)
#include <sys/types.h>
#include <sys/stat.h>
#if defined(__MBED__)
#include <platform/mbed_retarget.h>
#else
#include <dirent.h>
#endif
#include <errno.h>
#endif
#endif
x509_crt_verify_chain_item;
#define X509_MAX_VERIFY_CHAIN_SIZE …
const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_default = …;
const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_next = …;
const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_suiteb = …;
const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_none = …;
static int x509_profile_check_md_alg(const mbedtls_x509_crt_profile *profile,
mbedtls_md_type_t md_alg)
{ … }
static int x509_profile_check_pk_alg(const mbedtls_x509_crt_profile *profile,
mbedtls_pk_type_t pk_alg)
{ … }
static int x509_profile_check_key(const mbedtls_x509_crt_profile *profile,
const mbedtls_pk_context *pk)
{ … }
static int x509_memcasecmp(const void *s1, const void *s2, size_t len)
{ … }
static int x509_check_wildcard(const char *cn, const mbedtls_x509_buf *name)
{ … }
static int x509_string_cmp(const mbedtls_x509_buf *a, const mbedtls_x509_buf *b)
{ … }
static int x509_name_cmp(const mbedtls_x509_name *a, const mbedtls_x509_name *b)
{ … }
static void x509_crt_verify_chain_reset(
mbedtls_x509_crt_verify_chain *ver_chain)
{ … }
static int x509_get_version(unsigned char **p,
const unsigned char *end,
int *ver)
{ … }
static int x509_get_dates(unsigned char **p,
const unsigned char *end,
mbedtls_x509_time *from,
mbedtls_x509_time *to)
{ … }
static int x509_get_uid(unsigned char **p,
const unsigned char *end,
mbedtls_x509_buf *uid, int n)
{ … }
static int x509_get_basic_constraints(unsigned char **p,
const unsigned char *end,
int *ca_istrue,
int *max_pathlen)
{ … }
static int x509_get_ext_key_usage(unsigned char **p,
const unsigned char *end,
mbedtls_x509_sequence *ext_key_usage)
{ … }
static int x509_get_subject_key_id(unsigned char **p,
const unsigned char *end,
mbedtls_x509_buf *subject_key_id)
{ … }
static int x509_get_authority_key_id(unsigned char **p,
unsigned char *end,
mbedtls_x509_authority *authority_key_id)
{ … }
static int x509_get_certificate_policies(unsigned char **p,
const unsigned char *end,
mbedtls_x509_sequence *certificate_policies)
{ … }
static int x509_get_crt_ext(unsigned char **p,
const unsigned char *end,
mbedtls_x509_crt *crt,
mbedtls_x509_crt_ext_cb_t cb,
void *p_ctx)
{ … }
static int x509_crt_parse_der_core(mbedtls_x509_crt *crt,
const unsigned char *buf,
size_t buflen,
int make_copy,
mbedtls_x509_crt_ext_cb_t cb,
void *p_ctx)
{ … }
static int mbedtls_x509_crt_parse_der_internal(mbedtls_x509_crt *chain,
const unsigned char *buf,
size_t buflen,
int make_copy,
mbedtls_x509_crt_ext_cb_t cb,
void *p_ctx)
{ … }
int mbedtls_x509_crt_parse_der_nocopy(mbedtls_x509_crt *chain,
const unsigned char *buf,
size_t buflen)
{ … }
int mbedtls_x509_crt_parse_der_with_ext_cb(mbedtls_x509_crt *chain,
const unsigned char *buf,
size_t buflen,
int make_copy,
mbedtls_x509_crt_ext_cb_t cb,
void *p_ctx)
{ … }
int mbedtls_x509_crt_parse_der(mbedtls_x509_crt *chain,
const unsigned char *buf,
size_t buflen)
{ … }
int mbedtls_x509_crt_parse(mbedtls_x509_crt *chain,
const unsigned char *buf,
size_t buflen)
{ … }
#if defined(MBEDTLS_FS_IO)
int mbedtls_x509_crt_parse_file(mbedtls_x509_crt *chain, const char *path)
{ … }
int mbedtls_x509_crt_parse_path(mbedtls_x509_crt *chain, const char *path)
{ … }
#endif
#if !defined(MBEDTLS_X509_REMOVE_INFO)
#define PRINT_ITEM(i) …
#define CERT_TYPE(type, name) …
#define KEY_USAGE(code, name) …
static int x509_info_ext_key_usage(char **buf, size_t *size,
const mbedtls_x509_sequence *extended_key_usage)
{ … }
static int x509_info_cert_policies(char **buf, size_t *size,
const mbedtls_x509_sequence *certificate_policies)
{ … }
#define BEFORE_COLON …
#define BC …
int mbedtls_x509_crt_info(char *buf, size_t size, const char *prefix,
const mbedtls_x509_crt *crt)
{ … }
struct x509_crt_verify_string { … };
#define X509_CRT_ERROR_INFO …
static const struct x509_crt_verify_string x509_crt_verify_strings[] = …;
#undef X509_CRT_ERROR_INFO
int mbedtls_x509_crt_verify_info(char *buf, size_t size, const char *prefix,
uint32_t flags)
{ … }
#endif
int mbedtls_x509_crt_check_key_usage(const mbedtls_x509_crt *crt,
unsigned int usage)
{ … }
int mbedtls_x509_crt_check_extended_key_usage(const mbedtls_x509_crt *crt,
const char *usage_oid,
size_t usage_len)
{ … }
#if defined(MBEDTLS_X509_CRL_PARSE_C)
int mbedtls_x509_crt_is_revoked(const mbedtls_x509_crt *crt, const mbedtls_x509_crl *crl)
{ … }
static int x509_crt_verifycrl(mbedtls_x509_crt *crt, mbedtls_x509_crt *ca,
mbedtls_x509_crl *crl_list,
const mbedtls_x509_crt_profile *profile,
const mbedtls_x509_time *now)
{ … }
#endif
static int x509_crt_check_signature(const mbedtls_x509_crt *child,
mbedtls_x509_crt *parent,
mbedtls_x509_crt_restart_ctx *rs_ctx)
{ … }
static int x509_crt_check_parent(const mbedtls_x509_crt *child,
const mbedtls_x509_crt *parent,
int top)
{ … }
static int x509_crt_find_parent_in(
mbedtls_x509_crt *child,
mbedtls_x509_crt *candidates,
mbedtls_x509_crt **r_parent,
int *r_signature_is_good,
int top,
unsigned path_cnt,
unsigned self_cnt,
mbedtls_x509_crt_restart_ctx *rs_ctx,
const mbedtls_x509_time *now)
{ … }
static int x509_crt_find_parent(
mbedtls_x509_crt *child,
mbedtls_x509_crt *trust_ca,
mbedtls_x509_crt **parent,
int *parent_is_trusted,
int *signature_is_good,
unsigned path_cnt,
unsigned self_cnt,
mbedtls_x509_crt_restart_ctx *rs_ctx,
const mbedtls_x509_time *now)
{ … }
static int x509_crt_check_ee_locally_trusted(
mbedtls_x509_crt *crt,
mbedtls_x509_crt *trust_ca)
{ … }
static int x509_crt_verify_chain(
mbedtls_x509_crt *crt,
mbedtls_x509_crt *trust_ca,
mbedtls_x509_crl *ca_crl,
mbedtls_x509_crt_ca_cb_t f_ca_cb,
void *p_ca_cb,
const mbedtls_x509_crt_profile *profile,
mbedtls_x509_crt_verify_chain *ver_chain,
mbedtls_x509_crt_restart_ctx *rs_ctx)
{ … }
#ifdef _WIN32
#ifdef _MSC_VER
#pragma comment(lib, "ws2_32.lib")
#include <winsock2.h>
#include <ws2tcpip.h>
#elif (defined(__MINGW32__) || defined(__MINGW64__)) && _WIN32_WINNT >= 0x0600
#include <winsock2.h>
#include <ws2tcpip.h>
#else
#define MBEDTLS_TEST_SW_INET_PTON
#endif
#elif defined(__sun)
#elif defined(__has_include)
#if __has_include(<sys/socket.h>)
#include <sys/socket.h>
#endif
#if __has_include(<arpa/inet.h>)
#include <arpa/inet.h>
#endif
#endif
#if !defined(AF_INET6) || defined(MBEDTLS_TEST_SW_INET_PTON)
static int x509_inet_pton_ipv4(const char *src, void *dst);
#define li_cton …
static int x509_inet_pton_ipv6(const char *src, void *dst)
{
const unsigned char *p = (const unsigned char *) src;
int nonzero_groups = 0, num_digits, zero_group_start = -1;
uint16_t addr[8];
do {
uint16_t group = num_digits = 0;
for (uint8_t digit; num_digits < 4; num_digits++) {
if (li_cton(*p, digit) == 0) {
break;
}
group = (group << 4) | digit;
p++;
}
if (num_digits != 0) {
MBEDTLS_PUT_UINT16_BE(group, addr, nonzero_groups);
nonzero_groups++;
if (*p == '\0') {
break;
} else if (*p == '.') {
if ((nonzero_groups == 0 && zero_group_start == -1) ||
nonzero_groups >= 7) {
break;
}
int steps = 4;
do {
p--;
steps--;
} while (*p != ':' && steps > 0);
if (*p != ':') {
break;
}
p++;
nonzero_groups--;
if (x509_inet_pton_ipv4((const char *) p,
addr + nonzero_groups) != 0) {
break;
}
nonzero_groups += 2;
p = (const unsigned char *) "";
break;
} else if (*p != ':') {
return -1;
}
} else {
if (zero_group_start != -1 || *p != ':') {
return -1;
}
zero_group_start = nonzero_groups;
if (zero_group_start == 0 && *++p != ':') {
return -1;
}
if (p[1] == '\0') {
++p;
break;
}
}
++p;
} while (nonzero_groups < 8);
if (*p != '\0') {
return -1;
}
if (zero_group_start != -1) {
if (nonzero_groups > 6) {
return -1;
}
int zero_groups = 8 - nonzero_groups;
int groups_after_zero = nonzero_groups - zero_group_start;
if (groups_after_zero) {
memmove(addr + zero_group_start + zero_groups,
addr + zero_group_start,
groups_after_zero * sizeof(*addr));
}
memset(addr + zero_group_start, 0, zero_groups * sizeof(*addr));
} else {
if (nonzero_groups != 8) {
return -1;
}
}
memcpy(dst, addr, sizeof(addr));
return 0;
}
static int x509_inet_pton_ipv4(const char *src, void *dst)
{
const unsigned char *p = (const unsigned char *) src;
uint8_t *res = (uint8_t *) dst;
uint8_t digit, num_digits = 0;
uint8_t num_octets = 0;
uint16_t octet;
do {
octet = num_digits = 0;
do {
digit = *p - '0';
if (digit > 9) {
break;
}
if (octet == 0 && num_digits > 0) {
return -1;
}
octet = octet * 10 + digit;
num_digits++;
p++;
} while (num_digits < 3);
if (octet >= 256 || num_digits > 3 || num_digits == 0) {
return -1;
}
*res++ = (uint8_t) octet;
num_octets++;
} while (num_octets < 4 && *p++ == '.');
return num_octets == 4 && *p == '\0' ? 0 : -1;
}
#else
static int x509_inet_pton_ipv6(const char *src, void *dst)
{ … }
static int x509_inet_pton_ipv4(const char *src, void *dst)
{ … }
#endif
size_t mbedtls_x509_crt_parse_cn_inet_pton(const char *cn, void *dst)
{ … }
static int x509_crt_check_cn(const mbedtls_x509_buf *name,
const char *cn, size_t cn_len)
{ … }
static int x509_crt_check_san_ip(const mbedtls_x509_sequence *san,
const char *cn, size_t cn_len)
{ … }
static int x509_crt_check_san_uri(const mbedtls_x509_sequence *san,
const char *cn, size_t cn_len)
{ … }
static int x509_crt_check_san(const mbedtls_x509_sequence *san,
const char *cn, size_t cn_len)
{ … }
static void x509_crt_verify_name(const mbedtls_x509_crt *crt,
const char *cn,
uint32_t *flags)
{ … }
static int x509_crt_merge_flags_with_cb(
uint32_t *flags,
const mbedtls_x509_crt_verify_chain *ver_chain,
int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
void *p_vrfy)
{ … }
static int x509_crt_verify_restartable_ca_cb(mbedtls_x509_crt *crt,
mbedtls_x509_crt *trust_ca,
mbedtls_x509_crl *ca_crl,
mbedtls_x509_crt_ca_cb_t f_ca_cb,
void *p_ca_cb,
const mbedtls_x509_crt_profile *profile,
const char *cn, uint32_t *flags,
int (*f_vrfy)(void *,
mbedtls_x509_crt *,
int,
uint32_t *),
void *p_vrfy,
mbedtls_x509_crt_restart_ctx *rs_ctx)
{ … }
int mbedtls_x509_crt_verify(mbedtls_x509_crt *crt,
mbedtls_x509_crt *trust_ca,
mbedtls_x509_crl *ca_crl,
const char *cn, uint32_t *flags,
int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
void *p_vrfy)
{ … }
int mbedtls_x509_crt_verify_with_profile(mbedtls_x509_crt *crt,
mbedtls_x509_crt *trust_ca,
mbedtls_x509_crl *ca_crl,
const mbedtls_x509_crt_profile *profile,
const char *cn, uint32_t *flags,
int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
void *p_vrfy)
{ … }
#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
int mbedtls_x509_crt_verify_with_ca_cb(mbedtls_x509_crt *crt,
mbedtls_x509_crt_ca_cb_t f_ca_cb,
void *p_ca_cb,
const mbedtls_x509_crt_profile *profile,
const char *cn, uint32_t *flags,
int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
void *p_vrfy)
{
return x509_crt_verify_restartable_ca_cb(crt, NULL, NULL,
f_ca_cb, p_ca_cb,
profile, cn, flags,
f_vrfy, p_vrfy, NULL);
}
#endif
int mbedtls_x509_crt_verify_restartable(mbedtls_x509_crt *crt,
mbedtls_x509_crt *trust_ca,
mbedtls_x509_crl *ca_crl,
const mbedtls_x509_crt_profile *profile,
const char *cn, uint32_t *flags,
int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
void *p_vrfy,
mbedtls_x509_crt_restart_ctx *rs_ctx)
{ … }
void mbedtls_x509_crt_init(mbedtls_x509_crt *crt)
{ … }
void mbedtls_x509_crt_free(mbedtls_x509_crt *crt)
{ … }
#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
void mbedtls_x509_crt_restart_init(mbedtls_x509_crt_restart_ctx *ctx)
{
mbedtls_pk_restart_init(&ctx->pk);
ctx->parent = NULL;
ctx->fallback_parent = NULL;
ctx->fallback_signature_is_good = 0;
ctx->parent_is_trusted = -1;
ctx->in_progress = x509_crt_rs_none;
ctx->self_cnt = 0;
x509_crt_verify_chain_reset(&ctx->ver_chain);
}
void mbedtls_x509_crt_restart_free(mbedtls_x509_crt_restart_ctx *ctx)
{
if (ctx == NULL) {
return;
}
mbedtls_pk_restart_free(&ctx->pk);
mbedtls_x509_crt_restart_init(ctx);
}
#endif
int mbedtls_x509_crt_get_ca_istrue(const mbedtls_x509_crt *crt)
{ … }
#endif