159 lines
4.2 KiB
C
159 lines
4.2 KiB
C
|
#include <winpr/file.h>
|
||
|
#include <freerdp/crypto/crypto.h>
|
||
|
|
||
|
typedef char* (*get_field_pr)(X509*);
|
||
|
typedef struct
|
||
|
{
|
||
|
enum
|
||
|
{
|
||
|
DISABLED,
|
||
|
ENABLED,
|
||
|
} status;
|
||
|
const char* field_description;
|
||
|
get_field_pr get_field;
|
||
|
const char* expected_result;
|
||
|
} certificate_test_t;
|
||
|
|
||
|
static char* crypto_cert_subject_common_name_wo_length(X509* xcert)
|
||
|
{
|
||
|
int length;
|
||
|
return crypto_cert_subject_common_name(xcert, &length);
|
||
|
}
|
||
|
|
||
|
static char* certificate_path(void)
|
||
|
{
|
||
|
/*
|
||
|
Assume the .pem file is in the same directory as this source file.
|
||
|
Assume that __FILE__ will be a valid path to this file, even from the current working directory
|
||
|
where the tests are run. (ie. no chdir occurs between compilation and test running, or __FILE__
|
||
|
is an absolute path).
|
||
|
*/
|
||
|
static const char dirsep = '/';
|
||
|
static const char filename[] = "Test_x509_cert_info.pem";
|
||
|
#ifdef TEST_SOURCE_DIR
|
||
|
const char* file = TEST_SOURCE_DIR;
|
||
|
const size_t flen = sizeof(filename) + sizeof(dirsep) + strlen(file) + sizeof(char);
|
||
|
char* result = calloc(1, flen);
|
||
|
if (!result)
|
||
|
return NULL;
|
||
|
_snprintf(result, flen - 1, "%s%c%s", file, dirsep, filename);
|
||
|
return result;
|
||
|
#else
|
||
|
const char* file = __FILE__;
|
||
|
const char* last_dirsep = strrchr(file, dirsep);
|
||
|
|
||
|
if (last_dirsep)
|
||
|
{
|
||
|
const size_t filenameLen = strnlen(filename, sizeof(filename));
|
||
|
const size_t dirsepLen = last_dirsep - file + 1;
|
||
|
char* result = malloc(dirsepLen + filenameLen + 1);
|
||
|
if (!result)
|
||
|
return NULL;
|
||
|
strncpy(result, file, dirsepLen);
|
||
|
strncpy(result + dirsepLen, filename, filenameLen + 1);
|
||
|
return result;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
/* No dirsep => relative path in same directory */
|
||
|
return _strdup(filename);
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
static const certificate_test_t certificate_tests[] = {
|
||
|
|
||
|
{ ENABLED, "Certificate Common Name", crypto_cert_subject_common_name_wo_length,
|
||
|
"TESTJEAN TESTMARTIN 9999999" },
|
||
|
|
||
|
{ ENABLED, "Certificate subject", crypto_cert_subject,
|
||
|
"CN = TESTJEAN TESTMARTIN 9999999, C = FR, O = MINISTERE DES TESTS, OU = 0002 110014016, OU "
|
||
|
"= PERSONNES, UID = 9999999, GN = TESTJEAN, SN = TESTMARTIN" },
|
||
|
|
||
|
{ DISABLED, "Kerberos principal name", 0, "testjean.testmartin@kpn.test.example.com" },
|
||
|
|
||
|
{ ENABLED, "Certificate e-mail", crypto_cert_get_email, "testjean.testmartin@test.example.com"
|
||
|
|
||
|
},
|
||
|
|
||
|
{ ENABLED, "Microsoft's Universal Principal Name", crypto_cert_get_upn,
|
||
|
"testjean.testmartin.9999999@upn.test.example.com" },
|
||
|
|
||
|
{ ENABLED, "Certificate issuer", crypto_cert_issuer,
|
||
|
"CN = ADMINISTRATION CENTRALE DES TESTS, C = FR, O = MINISTERE DES TESTS, OU = 0002 "
|
||
|
"110014016" },
|
||
|
};
|
||
|
|
||
|
static int TestCertificateFile(const char* certificate_path,
|
||
|
const certificate_test_t* certificate_tests, int count)
|
||
|
{
|
||
|
X509* certificate;
|
||
|
FILE* certificate_file = winpr_fopen(certificate_path, "r");
|
||
|
int success = 0;
|
||
|
int i;
|
||
|
|
||
|
if (!certificate_file)
|
||
|
{
|
||
|
printf("%s: failure: cannot open certificate file '%s'\n", __FUNCTION__, certificate_path);
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
certificate = PEM_read_X509(certificate_file, 0, 0, 0);
|
||
|
fclose(certificate_file);
|
||
|
|
||
|
if (!certificate)
|
||
|
{
|
||
|
printf("%s: failure: cannot read certificate file '%s'\n", __FUNCTION__, certificate_path);
|
||
|
success = -1;
|
||
|
goto fail;
|
||
|
}
|
||
|
|
||
|
for (i = 0; i < count; i++)
|
||
|
{
|
||
|
char* result;
|
||
|
|
||
|
if (certificate_tests[i].status == DISABLED)
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
result = (certificate_tests[i].get_field ? certificate_tests[i].get_field(certificate) : 0);
|
||
|
|
||
|
if (result)
|
||
|
{
|
||
|
printf("%s: crypto got %-40s -> \"%s\"\n", __FUNCTION__,
|
||
|
certificate_tests[i].field_description, result);
|
||
|
|
||
|
if (0 != strcmp(result, certificate_tests[i].expected_result))
|
||
|
{
|
||
|
printf("%s: failure: for %s, actual: \"%s\", expected \"%s\"\n", __FUNCTION__,
|
||
|
certificate_tests[i].field_description, result,
|
||
|
certificate_tests[i].expected_result);
|
||
|
success = -1;
|
||
|
}
|
||
|
|
||
|
free(result);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
printf("%s: failure: cannot get %s\n", __FUNCTION__,
|
||
|
certificate_tests[i].field_description);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
fail:
|
||
|
X509_free(certificate);
|
||
|
return success;
|
||
|
}
|
||
|
|
||
|
int Test_x509_cert_info(int argc, char* argv[])
|
||
|
{
|
||
|
char* cert_path = certificate_path();
|
||
|
int ret;
|
||
|
WINPR_UNUSED(argc);
|
||
|
WINPR_UNUSED(argv);
|
||
|
ret = TestCertificateFile(cert_path, certificate_tests, ARRAYSIZE(certificate_tests));
|
||
|
free(cert_path);
|
||
|
return ret;
|
||
|
}
|