1 /***************************************************************************
2 * Copyright (c) 2024 Microsoft Corporation
3 *
4 * This program and the accompanying materials are made available under the
5 * terms of the MIT License which is available at
6 * https://opensource.org/licenses/MIT.
7 *
8 * SPDX-License-Identifier: MIT
9 **************************************************************************/
10
11
12 /**************************************************************************/
13 /**************************************************************************/
14 /** */
15 /** NetX Secure Component */
16 /** */
17 /** X.509 Digital Certificates */
18 /** */
19 /**************************************************************************/
20 /**************************************************************************/
21
22 #define NX_SECURE_SOURCE_CODE
23
24 #include "nx_secure_x509.h"
25
26 /**************************************************************************/
27 /* */
28 /* FUNCTION RELEASE */
29 /* */
30 /* _nx_secure_x509_common_name_dns_check PORTABLE C */
31 /* 6.1.6 */
32 /* AUTHOR */
33 /* */
34 /* Timothy Stapko, Microsoft Corporation */
35 /* */
36 /* DESCRIPTION */
37 /* */
38 /* This function checks a certificate's Common Name against a Top */
39 /* Level Domain name (TLD) provided by the caller for the purposes of */
40 /* DNS validation of a remote host. This utility function is intended */
41 /* to be called from within a certificate validation callback routine */
42 /* provided by the application. The TLD name should be the top part of */
43 /* the URL used to access the remote host (the "."-separated string */
44 /* before the first slash). */
45 /* */
46 /* NOTE 1: If the Common Name does not match the provided string, the */
47 /* "subject alt name" field is compared as well. */
48 /* */
49 /* NOTE 2: It is important to understand the format of the common name */
50 /* (and subject alt name) in expected certificates. For */
51 /* example, some certificates may use a raw IP address or a */
52 /* wild card. The DNS TLD string must be formatted such that */
53 /* it will match the expected values in received certificates. */
54 /* */
55 /* INPUT */
56 /* */
57 /* certificate Pointer to certificate */
58 /* dns_tld Top-level domain name */
59 /* dns_tls_length Length of TLS in bytes */
60 /* */
61 /* OUTPUT */
62 /* */
63 /* status Validity of certificate */
64 /* */
65 /* CALLS */
66 /* */
67 /* _nx_secure_x509_extension_find Find extension in certificate */
68 /* _nx_secure_x509_subject_alt_names_find */
69 /* Find subject alt names */
70 /* _nx_secure_x509_wildcard_compare Wildcard compare for names */
71 /* */
72 /* CALLED BY */
73 /* */
74 /* Application code */
75 /* */
76 /* RELEASE HISTORY */
77 /* */
78 /* DATE NAME DESCRIPTION */
79 /* */
80 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
81 /* 09-30-2020 Timothy Stapko Modified comment(s), */
82 /* resulting in version 6.1 */
83 /* 04-02-2021 Timothy Stapko Modified comment(s), */
84 /* removed dependency on TLS, */
85 /* resulting in version 6.1.6 */
86 /* */
87 /**************************************************************************/
_nx_secure_x509_common_name_dns_check(NX_SECURE_X509_CERT * certificate,const UCHAR * dns_tld,UINT dns_tld_length)88 UINT _nx_secure_x509_common_name_dns_check(NX_SECURE_X509_CERT *certificate, const UCHAR *dns_tld,
89 UINT dns_tld_length)
90 {
91 INT compare_value;
92 UINT status;
93 const UCHAR *common_name;
94 USHORT common_name_len;
95 NX_SECURE_X509_EXTENSION alt_name_extension;
96
97 /* Get access to our certificate fields. */
98 common_name = certificate -> nx_secure_x509_distinguished_name.nx_secure_x509_common_name;
99 common_name_len = certificate -> nx_secure_x509_distinguished_name.nx_secure_x509_common_name_length;
100
101 /* Compare the given string against the common name. */
102 compare_value = _nx_secure_x509_wildcard_compare(dns_tld, dns_tld_length, common_name, common_name_len);
103
104 if (compare_value == 0)
105 {
106 return(NX_SECURE_X509_SUCCESS);
107 }
108
109 /* Find the subject alt name extension in the certificate. */
110 status = _nx_secure_x509_extension_find(certificate, &alt_name_extension, NX_SECURE_TLS_X509_TYPE_SUBJECT_ALT_NAME);
111
112 /* See if extension present - it is OK if not present! */
113 if (status == NX_SECURE_X509_SUCCESS)
114 {
115 /* Extract the subject alt name string from the parsed extension. */
116 status = _nx_secure_x509_subject_alt_names_find(&alt_name_extension, dns_tld, dns_tld_length, NX_SECURE_X509_SUB_ALT_NAME_TAG_DNSNAME);
117
118 if (status == NX_SECURE_X509_SUCCESS)
119 {
120 return(NX_SECURE_X509_SUCCESS);
121 }
122 }
123
124 /* If we get here, none of the strings matched. */
125 return(NX_SECURE_X509_CERTIFICATE_DNS_MISMATCH);
126 }
127
128