Add support for needed functionality to mbedTLS
[platform/upstream/iotivity.git] / extlibs / mbedtls / ocf.patch
1 diff --git a/include/mbedtls/certs.h b/include/mbedtls/certs.h
2 index ca49086..e41de29 100644
3 --- a/include/mbedtls/certs.h
4 +++ b/include/mbedtls/certs.h
5 @@ -73,6 +73,10 @@ extern const char   mbedtls_test_cli_crt_ec[];
6  extern const size_t mbedtls_test_cli_crt_ec_len;
7  extern const char   mbedtls_test_cli_key_ec[];
8  extern const size_t mbedtls_test_cli_key_ec_len;
9 +#if defined(MBEDTLS_SHA256_C) && defined(MBEDTLS_X509_EXPANDED_SUBJECT_ALT_NAME_SUPPORT) && defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
10 +extern const char   mbedtls_test_srv_directoryname_ec_crt[];
11 +extern const size_t mbedtls_test_srv_directoryname_ec_crt_len;
12 +#endif
13  #endif
14  
15  #if defined(MBEDTLS_RSA_C)
16 diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h
17 index fe86c1e..e4583d6 100644
18 --- a/include/mbedtls/check_config.h
19 +++ b/include/mbedtls/check_config.h
20 @@ -189,6 +189,11 @@
21  #error "MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED defined, but not all prerequisites"
22  #endif
23  
24 +#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_ANON_ENABLED) &&                 \
25 +    ( !defined(MBEDTLS_ECDH_C) )
26 +#error "MBEDTLS_KEY_EXCHANGE_ECDH_ANON_ENABLED defined, but not all prerequisites"
27 +#endif
28 +
29  #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) &&                 \
30      ( !defined(MBEDTLS_ECDH_C) || !defined(MBEDTLS_ECDSA_C) ||          \
31        !defined(MBEDTLS_X509_CRT_PARSE_C) )
32 diff --git a/include/mbedtls/compat-1.3.h b/include/mbedtls/compat-1.3.h
33 index 27abbd9..fa4db26 100644
34 --- a/include/mbedtls/compat-1.3.h
35 +++ b/include/mbedtls/compat-1.3.h
36 @@ -264,6 +264,9 @@
37  #if defined MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
38  #define POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
39  #endif
40 +#if defined MBEDTLS_KEY_EXCHANGE_ECDH_ANON_ENABLED
41 +#define POLARSSL_KEY_EXCHANGE_ECDH_ANON_ENABLED MBEDTLS_KEY_EXCHANGE_ECDH_ANON_ENABLED
42 +#endif
43  #if defined MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED
44  #define POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED
45  #endif
46 @@ -1273,6 +1276,7 @@
47  #define POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA
48  #define POLARSSL_KEY_EXCHANGE_ECDHE_PSK MBEDTLS_KEY_EXCHANGE_ECDHE_PSK
49  #define POLARSSL_KEY_EXCHANGE_ECDHE_RSA MBEDTLS_KEY_EXCHANGE_ECDHE_RSA
50 +#define POLARSSL_KEY_EXCHANGE_ECDH_ANON MBEDTLS_KEY_EXCHANGE_ECDH_ANON
51  #define POLARSSL_KEY_EXCHANGE_ECDH_ECDSA MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA
52  #define POLARSSL_KEY_EXCHANGE_ECDH_RSA MBEDTLS_KEY_EXCHANGE_ECDH_RSA
53  #define POLARSSL_KEY_EXCHANGE_NONE MBEDTLS_KEY_EXCHANGE_NONE
54 @@ -1616,6 +1620,7 @@
55  #define TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384
56  #define TLS_ECDHE_RSA_WITH_NULL_SHA MBEDTLS_TLS_ECDHE_RSA_WITH_NULL_SHA
57  #define TLS_ECDHE_RSA_WITH_RC4_128_SHA MBEDTLS_TLS_ECDHE_RSA_WITH_RC4_128_SHA
58 +#define TLS_ECDH_ANON_WITH_AES_128_CBC_SHA256 MBEDTLS_TLS_ECDH_ANON_WITH_AES_128_CBC_SHA256
59  #define TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
60  #define TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
61  #define TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
62 diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h
63 index 6fc9c77..e6d300e 100644
64 --- a/include/mbedtls/config.h
65 +++ b/include/mbedtls/config.h
66 @@ -648,6 +648,21 @@
67  #define MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
68  
69  /**
70 + * \def MBEDTLS_KEY_EXCHANGE_ECDH_ANON_ENABLED
71 + *
72 + * Enable the ECDHE-ANON based ciphersuite modes in SSL / TLS.
73 + *
74 + * Requires: MBEDTLS_ECDH_C
75 + *
76 + *
77 + * This enables the following ciphersuites (if other requisites are
78 + * enabled as well):
79 + *      MBEDTLS_TLS_ECDH_ANON_WITH_AES_128_CBC_SHA256
80 + */
81 +#define MBEDTLS_KEY_EXCHANGE_ECDH_ANON_ENABLED
82 +
83 +
84 +/**
85   * \def MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
86   *
87   * Enable the ECDHE-ECDSA based ciphersuite modes in SSL / TLS.
88 @@ -1233,7 +1248,7 @@
89   *
90   * Comment this macro to disable support for SSL session tickets
91   */
92 -#define MBEDTLS_SSL_SESSION_TICKETS
93 +//#define MBEDTLS_SSL_SESSION_TICKETS
94  
95  /**
96   * \def MBEDTLS_SSL_EXPORT_KEYS
97 @@ -1360,6 +1375,21 @@
98  #define MBEDTLS_X509_RSASSA_PSS_SUPPORT
99  
100  /**
101 + * \def MBEDTLS_X509_EXPANDED_SUBJECT_ALT_NAME_SUPPORT
102 + *
103 + * Enable parsing of all supported subtypes of the Subject Alternative Name
104 + * extension. When enabled, the subject_alt_names field of mbedtls_x509_crt
105 + * is defined as an mbedtls_x509_subject_alt_name_sequence, each element of
106 + * which can describe a different subtype of the GeneralName choice as defined
107 + * by the standard.
108 + *
109 + * Comment this macro to only support dNSName subtypes, and to define the
110 + * subject_alt_names field as an mbedtls_x509_sequence. Any other subtypes will
111 + * be ignored. This was the behavior in earlier versions.
112 + */
113 +#define MBEDTLS_X509_EXPANDED_SUBJECT_ALT_NAME_SUPPORT
114 +
115 +/**
116   * \def MBEDTLS_ZLIB_SUPPORT
117   *
118   * If set, the SSL/TLS module uses ZLIB to support compression and
119 @@ -1473,6 +1503,7 @@
120   *      MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256
121   *      MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256
122   *      MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA
123 + *      MBEDTLS_TLS_ECDH_ANON_WITH_AES_128_CBC_SHA256
124   *
125   * PEM_PARSE uses AES for decrypting encrypted keys.
126   */
127 diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
128 index ba499d2..807bff6 100644
129 --- a/include/mbedtls/ssl.h
130 +++ b/include/mbedtls/ssl.h
131 @@ -358,7 +358,8 @@ union mbedtls_ssl_premaster_secret
132  #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED)    || \
133      defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)  || \
134      defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED)     || \
135 -    defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
136 +    defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)   || \
137 +    defined(MBEDTLS_KEY_EXCHANGE_ECDH_ANON_ENABLED)
138      unsigned char _pms_ecdh[MBEDTLS_ECP_MAX_BYTES];    /* RFC 4492 5.10 */
139  #endif
140  #if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED)
141 @@ -652,6 +653,12 @@ struct mbedtls_ssl_config
142      mbedtls_ssl_key_cert *key_cert; /*!< own certificate/key pair(s)        */
143      mbedtls_x509_crt *ca_chain;     /*!< trusted CAs                        */
144      mbedtls_x509_crl *ca_crl;       /*!< trusted CAs CRLs                   */
145 +#if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE)
146 +    const char *client_oid;         /*!< OID to check on client certs       */
147 +    size_t client_oid_len;          /*!< length of client OID               */
148 +    const char *server_oid;         /*!< OID to check on server certs       */
149 +    size_t server_oid_len;          /*!< length of server OID               */
150 +#endif /* MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE */
151  #endif /* MBEDTLS_X509_CRT_PARSE_C */
152  
153  #if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED)
154 @@ -1615,6 +1622,47 @@ void mbedtls_ssl_conf_ca_chain( mbedtls_ssl_config *conf,
155  int mbedtls_ssl_conf_own_cert( mbedtls_ssl_config *conf,
156                                mbedtls_x509_crt *own_cert,
157                                mbedtls_pk_context *pk_key );
158 +
159 +#if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE)
160 +/**
161 + * \brief                  Set custom EKU OIDs to be checked on certificates during TLS negotiation,
162 + *                         and for selecting suitable certificates for TLS negotation.
163 + *
164 + * \note                   By default, if this function is not called, clients will
165 + *                         check for the server authentication EKU (1.3.6.1.5.5.7.3.1) in
166 + *                         a server's certificate, and servers will check for the
167 + *                         client authentication EKU (1.3.6.1.5.5.7.3.2) if a client
168 + *                         presents a certificate. 
169 + *
170 + * \param conf             SSL configuration
171 + * \param client_oid       OID to check for when verifying client certificates as a server.
172 + *                         This must be an MBEDTLS_OID_* constant from oid.h, or a custom OID
173 + *                         supplied by the caller. If a custom OID is used, it must be provided in
174 + *                         its ASN.1 encoding; human-readable dotted numeric strings are not supported.
175 + *                         Additionally, callers using custom OID buffers must ensure those buffers remain
176 + *                         live while this SSL configuration is live. Passing NULL will
177 + *                         disable EKU checking of client certificates.
178 + * \param client_oid_len   The length of client_oid, not counting a terminating NULL if present; for constants
179 + *                         from oid.h, this can be obtained with MBEDTLS_OID_SIZE(x) where x is the OID constant.
180 + *                         If client_oid is NULL, this must be zero.
181 + * \param server_oid       OID to check for when verifying server certificates as a client.
182 + *                         This must be an MBEDTLS_OID_* constant from oid.h, or a custom OID
183 + *                         supplied by the caller. If a custom OID is used, it must be provided in
184 + *                         its ASN.1 encoding; human-readable dotted numeric strings are not supported.
185 + *                         Additionally, callers using custom OID buffers must ensure those buffers remain
186 + *                         live while this SSL configuration is live. Passing NULL will
187 + *                         disable EKU checking of server certificates.
188 + * \param server_oid_len   The length of server_oid not counting a terminating NULL if present; for constants
189 + *                         from oid.h, this can be obtained with MBEDTLS_OID_SIZE(x) where x is the OID constant.
190 + *                         If client_oid is NULL, this must be zero.
191 + *
192 + * \return                 0 on success or MBEDTLS_ERR_SSL_BAD_INPUT_DATA for invalid arguments.
193 + *                         On failure, existing behavior is unchanged.
194 + */
195 +int mbedtls_ssl_conf_ekus( mbedtls_ssl_config *conf,
196 +                           const char *client_oid, size_t client_oid_len,
197 +                           const char *server_oid, size_t server_oid_len );
198 +#endif /* MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE */
199  #endif /* MBEDTLS_X509_CRT_PARSE_C */
200  
201  #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
202 diff --git a/include/mbedtls/ssl_ciphersuites.h b/include/mbedtls/ssl_ciphersuites.h
203 index deaaa37..4f10540 100644
204 --- a/include/mbedtls/ssl_ciphersuites.h
205 +++ b/include/mbedtls/ssl_ciphersuites.h
206 @@ -158,6 +158,8 @@ extern "C" {
207  #define MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256     0xC031 /**< TLS 1.2 */
208  #define MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384     0xC032 /**< TLS 1.2 */
209  
210 +#define MBEDTLS_TLS_ECDH_ANON_WITH_AES_128_CBC_SHA256    0xFF00 /**< TLS 1.2 */
211 +
212  #define MBEDTLS_TLS_ECDHE_PSK_WITH_RC4_128_SHA           0xC033 /**< Not in SSL3! */
213  #define MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA      0xC034 /**< Not in SSL3! */
214  #define MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA       0xC035 /**< Not in SSL3! */
215 @@ -247,6 +249,7 @@ typedef enum {
216      MBEDTLS_KEY_EXCHANGE_ECDH_RSA,
217      MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA,
218      MBEDTLS_KEY_EXCHANGE_ECJPAKE,
219 +    MBEDTLS_KEY_EXCHANGE_ECDH_ANON,
220  } mbedtls_key_exchange_type_t;
221  
222  /* Key exchanges using a certificate */
223 @@ -271,7 +274,8 @@ typedef enum {
224  /* Key exchanges using a ECDHE */
225  #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED)     || \
226      defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)   || \
227 -    defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
228 +    defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)     || \
229 +    defined(MBEDTLS_KEY_EXCHANGE_ECDH_ANON_ENABLED)
230  #define MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED
231  #endif
232  
233 diff --git a/include/mbedtls/ssl_internal.h b/include/mbedtls/ssl_internal.h
234 index 668c0f5..e1035f9 100644
235 --- a/include/mbedtls/ssl_internal.h
236 +++ b/include/mbedtls/ssl_internal.h
237 @@ -437,6 +437,8 @@ static inline mbedtls_x509_crt *mbedtls_ssl_own_cert( mbedtls_ssl_context *ssl )
238  int mbedtls_ssl_check_cert_usage( const mbedtls_x509_crt *cert,
239                            const mbedtls_ssl_ciphersuite_t *ciphersuite,
240                            int cert_endpoint,
241 +                          const char *client_oid, size_t client_oid_len,
242 +                          const char *server_oid, size_t server_oid_len,
243                            uint32_t *flags );
244  #endif /* MBEDTLS_X509_CRT_PARSE_C */
245  
246 diff --git a/include/mbedtls/x509.h b/include/mbedtls/x509.h
247 index 54dac16..21f11a4 100644
248 --- a/include/mbedtls/x509.h
249 +++ b/include/mbedtls/x509.h
250 @@ -310,7 +310,7 @@ int mbedtls_x509_set_extension( mbedtls_asn1_named_data **head, const char *oid,
251  int mbedtls_x509_write_extensions( unsigned char **p, unsigned char *start,
252                             mbedtls_asn1_named_data *first );
253  int mbedtls_x509_write_names( unsigned char **p, unsigned char *start,
254 -                      mbedtls_asn1_named_data *first );
255 +                      const mbedtls_asn1_named_data *first );
256  int mbedtls_x509_write_sig( unsigned char **p, unsigned char *start,
257                      const char *oid, size_t oid_len,
258                      unsigned char *sig, size_t size );
259 diff --git a/include/mbedtls/x509_crt.h b/include/mbedtls/x509_crt.h
260 index 383e484..d4cdae1 100644
261 --- a/include/mbedtls/x509_crt.h
262 +++ b/include/mbedtls/x509_crt.h
263 @@ -46,6 +46,31 @@ extern "C" {
264   * \{
265   */
266  
267 +#if defined(MBEDTLS_X509_EXPANDED_SUBJECT_ALT_NAME_SUPPORT)
268 +typedef enum
269 +{
270 +    /* Don't use the value zero in this enum, because we use zero to denote an unset struct. */
271 +    MBEDTLS_X509_GENERALNAME_DNSNAME = 1,
272 +    MBEDTLS_X509_GENERALNAME_DIRECTORYNAME
273 +} mbedtls_x509_general_name_choice;
274 +
275 +typedef struct mbedtls_x509_general_name
276 +{
277 +    mbedtls_x509_general_name_choice name_type;
278 +    union
279 +    {
280 +        mbedtls_x509_buf dns_name;
281 +        mbedtls_x509_name *directory_name;
282 +    };
283 +} mbedtls_x509_general_name;
284 +
285 +typedef struct mbedtls_x509_general_names
286 +{
287 +    mbedtls_x509_general_name general_name;
288 +    struct mbedtls_x509_general_names *next;
289 +} mbedtls_x509_general_names;
290 +#endif
291 +
292  /**
293   * Container for an X.509 certificate. The certificate may be chained.
294   */
295 @@ -72,7 +97,11 @@ typedef struct mbedtls_x509_crt
296      mbedtls_x509_buf issuer_id;         /**< Optional X.509 v2/v3 issuer unique identifier. */
297      mbedtls_x509_buf subject_id;        /**< Optional X.509 v2/v3 subject unique identifier. */
298      mbedtls_x509_buf v3_ext;            /**< Optional X.509 v3 extensions.  */
299 +#if defined(MBEDTLS_X509_EXPANDED_SUBJECT_ALT_NAME_SUPPORT)
300 +    mbedtls_x509_general_names subject_alt_names; /**< Optional list of Subject Alternative Names (Only dNSName and directoryName supported). */
301 +#else
302      mbedtls_x509_sequence subject_alt_names;    /**< Optional list of Subject Alternative Names (Only dNSName supported). */
303 +#endif
304  
305      int ext_types;              /**< Bit string containing detected and parsed extensions */
306      int ca_istrue;              /**< Optional Basic Constraint extension value: 1 if this certificate belongs to a CA, 0 otherwise. */
307 @@ -593,6 +622,21 @@ int mbedtls_x509write_crt_set_key_usage( mbedtls_x509write_cert *ctx,
308  int mbedtls_x509write_crt_set_ns_cert_type( mbedtls_x509write_cert *ctx,
309                                      unsigned char ns_cert_type );
310  
311 +
312 +#if defined(MBEDTLS_X509_EXPANDED_SUBJECT_ALT_NAME_SUPPORT)
313 +/**
314 + * \brief           Set the subject alternative name extension
315 + *
316 + * \param ctx       CRT context to use
317 + * \param names     subject alternative names. For each dNSName element, the tag field of the dns_name
318 + *                  member does not need to be set and will be ignored.
319 + *
320 + * \return          0 if successful, or a specific error code
321 + */
322 +int mbedtls_x509write_crt_set_subject_alt_names( mbedtls_x509write_cert *ctx,
323 +                                                 const mbedtls_x509_general_names *names );
324 +#endif /* MBEDTLS_X509_EXPANDED_SUBJECT_ALT_NAME_SUPPORT */
325 +
326  /**
327   * \brief           Free the contents of a CRT write context
328   *
329 diff --git a/library/certs.c b/library/certs.c
330 index ffe6bc9..812969d 100644
331 --- a/library/certs.c
332 +++ b/library/certs.c
333 @@ -114,6 +114,23 @@ const size_t mbedtls_test_srv_crt_ec_len = sizeof( mbedtls_test_srv_crt_ec );
334  const size_t mbedtls_test_srv_key_ec_len = sizeof( mbedtls_test_srv_key_ec );
335  const size_t mbedtls_test_cli_crt_ec_len = sizeof( mbedtls_test_cli_crt_ec );
336  const size_t mbedtls_test_cli_key_ec_len = sizeof( mbedtls_test_cli_key_ec );
337 +
338 +#if defined(MBEDTLS_SHA256_C) && defined(MBEDTLS_X509_EXPANDED_SUBJECT_ALT_NAME_SUPPORT) && defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
339 +const char mbedtls_test_srv_directoryname_ec_crt[] =
340 +"-----BEGIN CERTIFICATE-----\r\n"
341 +"MIIBVzCB/qADAgECAgkAkWvgYjFeWV0wCgYIKoZIzj0EAwIwEzERMA8GA1UEAwwI\r\n"
342 +"VGVzdENlcnQwHhcNMTYxMjEzMjMwNDM3WhcNMzAwODIyMjMwNDM3WjATMREwDwYD\r\n"
343 +"VQQDDAhUZXN0Q2VydDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABOkrKfbStoGN\r\n"
344 +"oOUTet2ryyRul++FE++6vpEup83bHywiOO1a4JtDgzNJcjj8/uAKsECYQrI1T4Y/\r\n"
345 +"rpnYu8ff9VGjOzA5MDcGA1UdEQQwMC6kLDAqMRYwFAYDVQQLDA1OYW1lIEFzc2ln\r\n"
346 +"bmVyMRAwDgYDVQQDDAdNeSBSb2xlMAoGCCqGSM49BAMCA0gAMEUCIGdd/GGuoOXJ\r\n"
347 +"8Ipl3hy69gb35MmkwEQKuYrud+Qs5XfFAiEAsmEOP4KFZadL23XJfMfGuPn2MDLr\r\n"
348 +"G9lDDpiediVxGO0=\r\n"
349 +"-----END CERTIFICATE-----\r\n";
350 +
351 +const size_t mbedtls_test_srv_directoryname_ec_crt_len = sizeof( mbedtls_test_srv_directoryname_ec_crt );
352 +#endif
353 +
354  #else
355  #define TEST_CA_CRT_EC
356  #endif /* MBEDTLS_ECDSA_C */
357 diff --git a/library/entropy_poll.c b/library/entropy_poll.c
358 index a116e60..c022caf 100644
359 --- a/library/entropy_poll.c
360 +++ b/library/entropy_poll.c
361 @@ -54,28 +54,29 @@
362  #define _WIN32_WINNT 0x0400
363  #endif
364  #include <windows.h>
365 -#include <wincrypt.h>
366 +#include <bcrypt.h>
367  
368  int mbedtls_platform_entropy_poll( void *data, unsigned char *output, size_t len,
369                             size_t *olen )
370  {
371 -    HCRYPTPROV provider;
372      ((void) data);
373      *olen = 0;
374  
375 -    if( CryptAcquireContext( &provider, NULL, NULL,
376 -                              PROV_RSA_FULL, CRYPT_VERIFYCONTEXT ) == FALSE )
377 +    /*
378 +     * size_t may be 64 bits, but ULONG is always 32.
379 +     * If len is larger than the maximum for ULONG, just fail.
380 +     * It's unlikely anything ever will want to ask for this much randomness.
381 +     */
382 +    if ( len > 0xFFFFFFFFULL )
383      {
384          return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
385      }
386  
387 -    if( CryptGenRandom( provider, (DWORD) len, output ) == FALSE )
388 +    if ( !BCRYPT_SUCCESS(BCryptGenRandom(NULL, output, (ULONG) len, BCRYPT_USE_SYSTEM_PREFERRED_RNG)) )
389      {
390 -        CryptReleaseContext( provider, 0 );
391          return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
392      }
393  
394 -    CryptReleaseContext( provider, 0 );
395      *olen = len;
396  
397      return( 0 );
398 diff --git a/library/ssl_ciphersuites.c b/library/ssl_ciphersuites.c
399 index a762bf7..021ab50 100644
400 --- a/library/ssl_ciphersuites.c
401 +++ b/library/ssl_ciphersuites.c
402 @@ -95,6 +95,7 @@ static const int ciphersuite_preference[] =
403      MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
404      MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8,
405      MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM_8,
406 +    MBEDTLS_TLS_ECDH_ANON_WITH_AES_128_CBC_SHA256,
407  
408      /* All CAMELLIA-128 ephemeral suites */
409      MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256,
410 @@ -407,6 +408,22 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
411  #endif /* MBEDTLS_CIPHER_NULL_CIPHER */
412  #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
413  
414 +
415 +#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_ANON_ENABLED)
416 +#if defined(MBEDTLS_AES_C)
417 +#if defined(MBEDTLS_SHA256_C)
418 +#if defined(MBEDTLS_CIPHER_MODE_CBC)
419 +    { MBEDTLS_TLS_ECDH_ANON_WITH_AES_128_CBC_SHA256, "TLS-ECDH-ANON-WITH-AES-128-CBC-SHA256",
420 +      MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_ANON,
421 +      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
422 +      MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3,
423 +      0 },
424 +#endif /* MBEDTLS_CIPHER_MODE_CBC */
425 +#endif /* MBEDTLS_SHA256_C */
426 +#endif /* MBEDTLS_AES_C */
427 +#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_ANON_ENABLED */
428 +
429 +
430  #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED)
431  #if defined(MBEDTLS_AES_C)
432  #if defined(MBEDTLS_SHA1_C)
433 @@ -1829,6 +1846,7 @@ int mbedtls_ssl_ciphersuite_uses_ec( const mbedtls_ssl_ciphersuite_t *info )
434          case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK:
435          case MBEDTLS_KEY_EXCHANGE_ECDH_RSA:
436          case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA:
437 +        case MBEDTLS_KEY_EXCHANGE_ECDH_ANON:
438              return( 1 );
439  
440          default:
441 diff --git a/library/ssl_cli.c b/library/ssl_cli.c
442 index 223823b..945c973 100644
443 --- a/library/ssl_cli.c
444 +++ b/library/ssl_cli.c
445 @@ -1904,7 +1904,8 @@ static int ssl_parse_server_dh_params( mbedtls_ssl_context *ssl, unsigned char *
446      defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) ||                   \
447      defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) ||                     \
448      defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) ||                      \
449 -    defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
450 +    defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) ||                    \
451 +    defined(MBEDTLS_KEY_EXCHANGE_ECDH_ANON_ENABLED)
452  static int ssl_check_server_ecdh_params( const mbedtls_ssl_context *ssl )
453  {
454      const mbedtls_ecp_curve_info *curve_info;
455 @@ -1934,11 +1935,13 @@ static int ssl_check_server_ecdh_params( const mbedtls_ssl_context *ssl )
456            MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ||
457            MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED ||
458            MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED ||
459 -          MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
460 +          MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED ||
461 +          MBEDTLS_KEY_EXCHANGE_ECDH_ANON_ENABLED */
462  
463  #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) ||                     \
464      defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) ||                   \
465 -    defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED)
466 +    defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) ||                     \
467 +    defined(MBEDTLS_KEY_EXCHANGE_ECDH_ANON_ENABLED)
468  static int ssl_parse_server_ecdh_params( mbedtls_ssl_context *ssl,
469                                           unsigned char **p,
470                                           unsigned char *end )
471 @@ -1970,40 +1973,80 @@ static int ssl_parse_server_ecdh_params( mbedtls_ssl_context *ssl,
472  }
473  #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
474            MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ||
475 -          MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
476 +          MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED ||
477 +          MBEDTLS_KEY_EXCHANGE_ECDH_ANON_ENABLED*/
478  
479  #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
480  static int ssl_parse_server_psk_hint( mbedtls_ssl_context *ssl,
481                                        unsigned char **p,
482                                        unsigned char *end )
483  {
484 -    int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
485 -    size_t  len;
486 -    ((void) ssl);
487 +    int ret = 0;
488 +    size_t n;
489 +
490 +    if( ssl->conf->f_psk == NULL &&
491 +        ( ssl->conf->psk == NULL || ssl->conf->psk_identity == NULL ||
492 +          ssl->conf->psk_identity_len == 0 || ssl->conf->psk_len == 0 ) )
493 +    {
494 +        MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no pre-shared key" ) );
495 +        return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED );
496 +    }
497  
498      /*
499 -     * PSK parameters:
500 -     *
501 -     * opaque psk_identity_hint<0..2^16-1>;
502 +     * Receive client pre-shared key identity name
503       */
504 -    len = (*p)[0] << 8 | (*p)[1];
505 +    if( *p + 2 > end )
506 +    {
507 +        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
508 +        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
509 +    }
510 +
511 +    n = ( (*p)[0] << 8 ) | (*p)[1];
512      *p += 2;
513  
514 -    if( (*p) + len > end )
515 +    if (n == 0)
516      {
517 -        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message (psk_identity_hint length)" ) );
518 -        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
519 +        return ( 0 );
520      }
521  
522 -    /*
523 -     * Note: we currently ignore the PKS identity hint, as we only allow one
524 -     * PSK to be provisionned on the client. This could be changed later if
525 -     * someone needs that feature.
526 -     */
527 -    *p += len;
528 -    ret = 0;
529 +    if( n < 1 || n > 65535 || *p + n > end )
530 +    {
531 +        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
532 +        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
533 +    }
534  
535 -    return( ret );
536 +    if( ssl->conf->f_psk != NULL )
537 +    {
538 +        if( ssl->conf->f_psk( ssl->conf->p_psk, ssl, *p, n ) != 0 )
539 +            ret = MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY;
540 +    }
541 +    else
542 +    {
543 +        /* Identity is not a big secret since clients send it in the clear,
544 +         * but treat it carefully anyway, just in case */
545 +        if( n != ssl->conf->psk_identity_len ||
546 +            mbedtls_ssl_safer_memcmp( ssl->conf->psk_identity, *p, n ) != 0 )
547 +        {
548 +            ret = MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY;
549 +        }
550 +    }
551 +
552 +    if( ret == MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY )
553 +    {
554 +        MBEDTLS_SSL_DEBUG_BUF( 3, "Unknown PSK identity", *p, n );
555 +        if( ( ret = mbedtls_ssl_send_alert_message( ssl,
556 +                              MBEDTLS_SSL_ALERT_LEVEL_FATAL,
557 +                              MBEDTLS_SSL_ALERT_MSG_UNKNOWN_PSK_IDENTITY ) ) != 0 )
558 +        {
559 +            return( ret );
560 +        }
561 +
562 +        return( MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY );
563 +    }
564 +
565 +    *p += n;
566 +
567 +    return( 0 );
568  }
569  #endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
570  
571 @@ -2299,10 +2342,12 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl )
572            MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
573  #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) ||                     \
574      defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) ||                     \
575 -    defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
576 +    defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) ||                   \
577 +    defined(MBEDTLS_KEY_EXCHANGE_ECDH_ANON_ENABLED)
578      if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA ||
579          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
580 -        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA )
581 +        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA ||
582 +        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ANON )
583      {
584          if( ssl_parse_server_ecdh_params( ssl, &p, end ) != 0 )
585          {
586 @@ -2313,7 +2358,8 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl )
587      else
588  #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
589            MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED ||
590 -          MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
591 +          MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ||
592 +          MBEDTLS_KEY_EXCHANGE_ECDH_ANON_ENABLED */
593  #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
594      if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
595      {
596 @@ -2384,6 +2430,10 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl )
597              return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
598          }
599  
600 +// Anonim cipher suite without sign, ecdh param only
601 +#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_ANON_ENABLED)
602 +        goto exit;
603 +#endif
604          /*
605           * Read signature
606           */
607 @@ -2534,7 +2584,8 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
608          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
609          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
610          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
611 -        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
612 +        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ||
613 +        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ANON )
614      {
615          MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate request" ) );
616          ssl->state++;
617 @@ -2559,7 +2610,8 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
618          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
619          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
620          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
621 -        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
622 +        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ||
623 +        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ANON )
624      {
625          MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate request" ) );
626          ssl->state++;
627 @@ -2773,11 +2825,13 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl )
628  #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) ||                     \
629      defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) ||                   \
630      defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) ||                      \
631 -    defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
632 +    defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) ||                    \
633 +    defined(MBEDTLS_KEY_EXCHANGE_ECDH_ANON_ENABLED)
634      if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA ||
635          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA ||
636          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_RSA ||
637 -        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA )
638 +        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA ||
639 +        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ANON)
640      {
641          /*
642           * ECDH key exchange -- send client public value
643 @@ -2812,7 +2866,8 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl )
644  #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
645            MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ||
646            MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED ||
647 -          MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */
648 +          MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED
649 +          MBEDTLS_KEY_EXCHANGE_ECDH_ANON_ENABLED */
650  #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
651      if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
652          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
653 @@ -3002,7 +3057,8 @@ static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
654          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
655          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
656          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
657 -        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
658 +        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ||
659 +        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ANON )
660      {
661          MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) );
662          ssl->state++;
663 @@ -3035,7 +3091,8 @@ static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
664          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
665          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
666          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
667 -        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
668 +        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ||
669 +        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ANON )
670      {
671          MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) );
672          ssl->state++;
673 diff --git a/library/ssl_srv.c b/library/ssl_srv.c
674 index fc0d2d7..18f89cd 100644
675 --- a/library/ssl_srv.c
676 +++ b/library/ssl_srv.c
677 @@ -648,7 +648,15 @@ static int ssl_pick_cert( mbedtls_ssl_context *ssl,
678           * and decrypting with the same RSA key.
679           */
680          if( mbedtls_ssl_check_cert_usage( cur->cert, ciphersuite_info,
681 -                                  MBEDTLS_SSL_IS_SERVER, &flags ) != 0 )
682 +                                  MBEDTLS_SSL_IS_SERVER, 
683 +#if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE)
684 +                                  ssl->conf->client_oid, ssl->conf->client_oid_len,
685 +                                  ssl->conf->server_oid, ssl->conf->server_oid_len,
686 +#else
687 +                                  NULL, 0,
688 +                                  NULL, 0,
689 +#endif
690 +                                  &flags ) != 0 )
691          {
692              MBEDTLS_SSL_DEBUG_MSG( 3, ( "certificate mismatch: "
693                                  "(extended) key usage extension" ) );
694 @@ -2498,6 +2506,7 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
695          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
696          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
697          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ||
698 +        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ANON ||
699          authmode == MBEDTLS_SSL_VERIFY_NONE )
700      {
701          MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate request" ) );
702 @@ -2675,7 +2684,8 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
703      defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) ||                     \
704      defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) ||                     \
705      defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) ||                   \
706 -    defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
707 +    defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) ||                        \
708 +    defined(MBEDTLS_KEY_EXCHANGE_ECDH_ANON_ENABLED)
709      unsigned char *p = ssl->out_msg + 4;
710      unsigned char *dig_signed = p;
711      size_t dig_signed_len = 0, len;
712 @@ -2736,12 +2746,11 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
713      if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
714          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK )
715      {
716 -        /* Note: we don't support identity hints, until someone asks
717 -         * for them. */
718 -        *(p++) = 0x00;
719 -        *(p++) = 0x00;
720 -
721 -        n += 2;
722 +        *(p++) = (unsigned char)( ssl->conf->psk_identity_len >> 8 );
723 +        *(p++) = (unsigned char)( ssl->conf->psk_identity_len      );
724 +        memcpy(p, ssl->conf->psk_identity, ssl->conf->psk_identity_len);
725 +        p += ssl->conf->psk_identity_len;
726 +        n += ssl->conf->psk_identity_len + 2;
727      }
728  #endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED ||
729            MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
730 @@ -2798,7 +2807,8 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
731  #if defined(MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED)
732      if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA ||
733          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA ||
734 -        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK )
735 +        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
736 +        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ANON)
737      {
738          /*
739           * Ephemeral ECDH parameters:
740 @@ -3336,11 +3346,13 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl )
741  #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) ||                     \
742      defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) ||                   \
743      defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) ||                      \
744 -    defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)
745 +    defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) ||                    \
746 +    defined(MBEDTLS_KEY_EXCHANGE_ECDH_ANON_ENABLED)
747      if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA ||
748          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA ||
749          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_RSA ||
750 -        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA )
751 +        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA ||
752 +        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ANON )
753      {
754          if( ( ret = mbedtls_ecdh_read_public( &ssl->handshake->ecdh_ctx,
755                                        p, end - p) ) != 0 )
756 @@ -3539,7 +3551,8 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
757          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
758          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
759          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
760 -        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
761 +        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ||
762 +        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ANON )
763      {
764          MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate verify" ) );
765          ssl->state++;
766 @@ -3570,6 +3583,7 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
767          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
768          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
769          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ||
770 +        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ANON ||
771          ssl->session_negotiate->peer_cert == NULL )
772      {
773          MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate verify" ) );
774 diff --git a/library/ssl_tls.c b/library/ssl_tls.c
775 index 84a04ae..2f23a3e 100644
776 --- a/library/ssl_tls.c
777 +++ b/library/ssl_tls.c
778 @@ -4066,7 +4066,8 @@ int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl )
779      if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
780          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
781          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
782 -        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
783 +        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ||
784 +        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ANON )
785      {
786          MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) );
787          ssl->state++;
788 @@ -4086,7 +4087,8 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl )
789      if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
790          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
791          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
792 -        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
793 +        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ||
794 +        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ANON )
795      {
796          MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) );
797          ssl->state++;
798 @@ -4109,7 +4111,8 @@ int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl )
799      if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
800          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
801          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
802 -        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
803 +        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ||
804 +        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ANON )
805      {
806          MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) );
807          ssl->state++;
808 @@ -4225,7 +4228,8 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl )
809      if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
810          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
811          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
812 -        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
813 +        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ||
814 +        ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ANON )
815      {
816          MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) );
817          ssl->state++;
818 @@ -4476,6 +4480,13 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl )
819          if( mbedtls_ssl_check_cert_usage( ssl->session_negotiate->peer_cert,
820                                    ciphersuite_info,
821                                    ! ssl->conf->endpoint,
822 +#if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE)
823 +                                  ssl->conf->client_oid, ssl->conf->client_oid_len,
824 +                                  ssl->conf->server_oid, ssl->conf->server_oid_len,
825 +#else
826 +                                  NULL, 0,
827 +                                  NULL, 0,
828 +#endif
829                                   &ssl->session_negotiate->verify_result ) != 0 )
830          {
831              MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate (usage extensions)" ) );
832 @@ -5759,6 +5770,28 @@ int mbedtls_ssl_conf_own_cert( mbedtls_ssl_config *conf,
833      return( ssl_append_key_cert( &conf->key_cert, own_cert, pk_key ) );
834  }
835  
836 +#if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE)
837 +int mbedtls_ssl_conf_ekus( mbedtls_ssl_config *conf,
838 +                           const char *client_oid, size_t client_oid_len,
839 +                           const char *server_oid, size_t server_oid_len )
840 +{
841 +    if( ( client_oid_len == 0 && client_oid )  ||
842 +        ( client_oid_len != 0 && !client_oid ) ||
843 +        ( server_oid_len == 0 && server_oid )  ||
844 +        ( server_oid_len != 0 && !server_oid ) )
845 +    {
846 +        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
847 +    }
848 +
849 +    conf->client_oid = client_oid;
850 +    conf->client_oid_len = client_oid_len;
851 +    conf->server_oid = server_oid;
852 +    conf->server_oid_len = server_oid_len;
853 +
854 +    return( 0 );
855 +}
856 +#endif /* MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE */
857 +
858  void mbedtls_ssl_conf_ca_chain( mbedtls_ssl_config *conf,
859                                 mbedtls_x509_crt *ca_chain,
860                                 mbedtls_x509_crl *ca_crl )
861 @@ -7246,6 +7279,13 @@ int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf,
862              }
863  #endif
864  
865 +#if defined(MBEDTLS_X509_CRT_PARSE_C) && defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE)
866 +    conf->client_oid = MBEDTLS_OID_CLIENT_AUTH;
867 +    conf->client_oid_len = MBEDTLS_OID_SIZE( MBEDTLS_OID_CLIENT_AUTH );
868 +    conf->server_oid = MBEDTLS_OID_SERVER_AUTH;
869 +    conf->server_oid_len = MBEDTLS_OID_SIZE( MBEDTLS_OID_SERVER_AUTH );
870 +#endif
871 +
872      /*
873       * Preset-specific defaults
874       */
875 @@ -7493,6 +7533,8 @@ int mbedtls_ssl_check_sig_hash( const mbedtls_ssl_context *ssl,
876  int mbedtls_ssl_check_cert_usage( const mbedtls_x509_crt *cert,
877                            const mbedtls_ssl_ciphersuite_t *ciphersuite,
878                            int cert_endpoint,
879 +                          const char *client_oid, size_t client_oid_len,
880 +                          const char *server_oid, size_t server_oid_len,
881                            uint32_t *flags )
882  {
883      int ret = 0;
884 @@ -7509,6 +7551,10 @@ int mbedtls_ssl_check_cert_usage( const mbedtls_x509_crt *cert,
885      ((void) cert);
886      ((void) cert_endpoint);
887      ((void) flags);
888 +    ((void) client_oid);
889 +    ((void) client_oid_len);
890 +    ((void) server_oid);
891 +    ((void) server_oid_len);
892  #endif
893  
894  #if defined(MBEDTLS_X509_CHECK_KEY_USAGE)
895 @@ -7539,6 +7585,7 @@ int mbedtls_ssl_check_cert_usage( const mbedtls_x509_crt *cert,
896              case MBEDTLS_KEY_EXCHANGE_DHE_PSK:
897              case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK:
898              case MBEDTLS_KEY_EXCHANGE_ECJPAKE:
899 +            case MBEDTLS_KEY_EXCHANGE_ECDH_ANON:
900                  usage = 0;
901          }
902      }
903 @@ -7560,13 +7607,13 @@ int mbedtls_ssl_check_cert_usage( const mbedtls_x509_crt *cert,
904  #if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE)
905      if( cert_endpoint == MBEDTLS_SSL_IS_SERVER )
906      {
907 -        ext_oid = MBEDTLS_OID_SERVER_AUTH;
908 -        ext_len = MBEDTLS_OID_SIZE( MBEDTLS_OID_SERVER_AUTH );
909 +        ext_oid = server_oid;
910 +        ext_len = server_oid_len;
911      }
912      else
913      {
914 -        ext_oid = MBEDTLS_OID_CLIENT_AUTH;
915 -        ext_len = MBEDTLS_OID_SIZE( MBEDTLS_OID_CLIENT_AUTH );
916 +        ext_oid = client_oid;
917 +        ext_len = client_oid_len;
918      }
919  
920      if( mbedtls_x509_crt_check_extended_key_usage( cert, ext_oid, ext_len ) != 0 )
921 diff --git a/library/version_features.c b/library/version_features.c
922 index e866e67..7798b27 100644
923 --- a/library/version_features.c
924 +++ b/library/version_features.c
925 @@ -264,6 +264,9 @@ static const char *features[] = {
926  #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED)
927      "MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED",
928  #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED */
929 +#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_ANON_ENABLED)
930 +    "MBEDTLS_KEY_EXCHANGE_ECDH_ANON_ENABLED",
931 +#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_ANON_ENABLED */
932  #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)
933      "MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED",
934  #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
935 @@ -423,6 +426,9 @@ static const char *features[] = {
936  #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
937      "MBEDTLS_X509_RSASSA_PSS_SUPPORT",
938  #endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */
939 +#if defined(MBEDTLS_X509_EXPANDED_SUBJECT_ALT_NAME_SUPPORT)
940 +    "MBEDTLS_X509_EXPANDED_SUBJECT_ALT_NAME_SUPPORT",
941 +#endif /* MBEDTLS_X509_EXPANDED_SUBJECT_ALT_NAME_SUPPORT */
942  #if defined(MBEDTLS_ZLIB_SUPPORT)
943      "MBEDTLS_ZLIB_SUPPORT",
944  #endif /* MBEDTLS_ZLIB_SUPPORT */
945 diff --git a/library/x509.c b/library/x509.c
946 index fad390d..0bc5367 100644
947 --- a/library/x509.c
948 +++ b/library/x509.c
949 @@ -1005,6 +1005,10 @@ int mbedtls_x509_self_test( int verbose )
950      uint32_t flags;
951      mbedtls_x509_crt cacert;
952      mbedtls_x509_crt clicert;
953 +#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_SHA256_C) && defined(MBEDTLS_X509_EXPANDED_SUBJECT_ALT_NAME_SUPPORT) && defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
954 +    mbedtls_x509_crt directorynamecert;
955 +    char buf[2048];
956 +#endif
957  
958      if( verbose != 0 )
959          mbedtls_printf( "  X.509 certificate load: " );
960 @@ -1045,11 +1049,45 @@ int mbedtls_x509_self_test( int verbose )
961          return( ret );
962      }
963  
964 +#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_SHA256_C) && defined(MBEDTLS_X509_EXPANDED_SUBJECT_ALT_NAME_SUPPORT) && defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
965 +    if( verbose != 0 )
966 +        mbedtls_printf( "passed\n  X.509 subject alt name verify: " );
967 +
968 +    mbedtls_x509_crt_init( &directorynamecert );
969 +
970 +    ret = mbedtls_x509_crt_parse( &directorynamecert, (const unsigned char *) mbedtls_test_srv_directoryname_ec_crt,
971 +                                  mbedtls_test_srv_directoryname_ec_crt_len );
972 +
973 +    if( ret != 0 )
974 +    {
975 +        if( verbose != 0 )
976 +            mbedtls_printf( "failed\n" );
977 +
978 +        return( ret );
979 +    }
980 +
981 +    if( verbose != 0 )
982 +        mbedtls_printf( "passed\n  X.509 directoryName parsing: " );
983 +
984 +    ret = mbedtls_x509_crt_info( buf, sizeof( buf ), "", &directorynamecert );
985 +    if ( ret < 0 )
986 +    {
987 +        if ( verbose != 0 )
988 +            mbedtls_printf( "failed\n" );
989 +
990 +        return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
991 +    }
992 +
993 +#endif
994 +
995      if( verbose != 0 )
996 -        mbedtls_printf( "passed\n\n");
997 +        mbedtls_printf( "passed\n\n" );
998  
999      mbedtls_x509_crt_free( &cacert  );
1000      mbedtls_x509_crt_free( &clicert );
1001 +#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_SHA256_C) && defined(MBEDTLS_X509_EXPANDED_SUBJECT_ALT_NAME_SUPPORT) && defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
1002 +    mbedtls_x509_crt_free( &directorynamecert );
1003 +#endif
1004  
1005      return( 0 );
1006  #else
1007 diff --git a/library/x509_create.c b/library/x509_create.c
1008 index df20ec8..5faec78 100644
1009 --- a/library/x509_create.c
1010 +++ b/library/x509_create.c
1011 @@ -231,15 +231,15 @@ static int x509_write_name( unsigned char **p, unsigned char *start,
1012  }
1013  
1014  int mbedtls_x509_write_names( unsigned char **p, unsigned char *start,
1015 -                      mbedtls_asn1_named_data *first )
1016 +                      const mbedtls_asn1_named_data *first )
1017  {
1018      int ret;
1019      size_t len = 0;
1020 -    mbedtls_asn1_named_data *cur = first;
1021 +    const mbedtls_asn1_named_data *cur = first;
1022  
1023      while( cur != NULL )
1024      {
1025 -        MBEDTLS_ASN1_CHK_ADD( len, x509_write_name( p, start, (char *) cur->oid.p,
1026 +        MBEDTLS_ASN1_CHK_ADD( len, x509_write_name( p, start, (const char *) cur->oid.p,
1027                                              cur->oid.len,
1028                                              cur->val.p, cur->val.len ) );
1029          cur = cur->next;
1030 diff --git a/library/x509_crt.c b/library/x509_crt.c
1031 index 60e14f9..037efae 100644
1032 --- a/library/x509_crt.c
1033 +++ b/library/x509_crt.c
1034 @@ -62,6 +62,7 @@
1035  
1036  #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
1037  #include <windows.h>
1038 +#include <intsafe.h>
1039  #else
1040  #include <time.h>
1041  #endif
1042 @@ -438,17 +439,31 @@ static int x509_get_ext_key_usage( unsigned char **p,
1043   *      nameAssigner            [0]     DirectoryString OPTIONAL,
1044   *      partyName               [1]     DirectoryString }
1045   *
1046 - * NOTE: we only parse and use dNSName at this point.
1047 + * NOTE: If MBEDTLS_X509_EXPANDED_SUBJECT_ALT_NAME_SUPPORT is not defined, we only parse and use dNSName.
1048 + * If it is defined, we parse and use all supported types, which are currently dNSName and directoryName.
1049   */
1050 +#if defined(MBEDTLS_X509_EXPANDED_SUBJECT_ALT_NAME_SUPPORT)
1051 +static int x509_get_subject_alt_name( unsigned char **p,
1052 +                                      const unsigned char *end,
1053 +                                      mbedtls_x509_general_names *subject_alt_name )
1054 +
1055 +#else
1056  static int x509_get_subject_alt_name( unsigned char **p,
1057                                        const unsigned char *end,
1058                                        mbedtls_x509_sequence *subject_alt_name )
1059 +#endif
1060  {
1061      int ret;
1062      size_t len, tag_len;
1063 -    mbedtls_asn1_buf *buf;
1064      unsigned char tag;
1065 +#if defined(MBEDTLS_X509_EXPANDED_SUBJECT_ALT_NAME_SUPPORT)
1066 +    mbedtls_x509_general_names *cur = subject_alt_name;
1067 +    mbedtls_x509_general_name general_name;
1068 +    size_t name_len;
1069 +#else
1070 +    mbedtls_asn1_buf *buf;
1071      mbedtls_asn1_sequence *cur = subject_alt_name;
1072 +#endif
1073  
1074      /* Get main sequence tag */
1075      if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
1076 @@ -474,6 +489,49 @@ static int x509_get_subject_alt_name( unsigned char **p,
1077              return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
1078                      MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
1079  
1080 +#if defined(MBEDTLS_X509_EXPANDED_SUBJECT_ALT_NAME_SUPPORT)
1081 +        memset( &general_name, 0, sizeof( general_name ) );
1082 +        switch ( tag )
1083 +        {
1084 +        case ( MBEDTLS_ASN1_CONTEXT_SPECIFIC | 2 ): /* dNSName */
1085 +            general_name.name_type = MBEDTLS_X509_GENERALNAME_DNSNAME;
1086 +            general_name.dns_name.tag = tag;
1087 +            general_name.dns_name.p = *p;
1088 +            general_name.dns_name.len = tag_len;
1089 +            *p += tag_len;
1090 +            break;
1091 +        case ( MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 4 ): /* directoryName */
1092 +            general_name.name_type = MBEDTLS_X509_GENERALNAME_DIRECTORYNAME;
1093 +            if( ( ret = mbedtls_asn1_get_tag( p, end, &name_len,
1094 +                    MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
1095 +                return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
1096 +            general_name.directory_name = mbedtls_calloc( 1, sizeof( mbedtls_x509_name ) );
1097 +            if ( general_name.directory_name == NULL )
1098 +                return( MBEDTLS_ERR_X509_ALLOC_FAILED );
1099 +            if( ( ret = mbedtls_x509_get_name( p, *p + name_len, general_name.directory_name ) ) != 0 )
1100 +                return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
1101 +            break;
1102 +        default:
1103 +            *p += tag_len;
1104 +            continue;
1105 +        }
1106 +
1107 +        if( cur->general_name.name_type != 0 )
1108 +        {
1109 +            if( cur->next != NULL )
1110 +                return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS );
1111 +
1112 +            cur->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_general_names ) );
1113 +
1114 +            if( cur->next == NULL )
1115 +                return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
1116 +                        MBEDTLS_ERR_ASN1_ALLOC_FAILED );
1117 +
1118 +            cur = cur->next;
1119 +        }
1120 +
1121 +        memcpy( &cur->general_name, &general_name, sizeof( general_name ) );
1122 +#else
1123          /* Skip everything but DNS name */
1124          if( tag != ( MBEDTLS_ASN1_CONTEXT_SPECIFIC | 2 ) )
1125          {
1126 @@ -501,6 +559,7 @@ static int x509_get_subject_alt_name( unsigned char **p,
1127          buf->p = *p;
1128          buf->len = tag_len;
1129          *p += buf->len;
1130 +#endif
1131      }
1132  
1133      /* Set final sequence entry's next pointer to NULL */
1134 @@ -1108,6 +1167,7 @@ int mbedtls_x509_crt_parse_path( mbedtls_x509_crt *chain, const char *path )
1135      char filename[MAX_PATH];
1136      char *p;
1137      size_t len = strlen( path );
1138 +    int lengthAsInt = 0;
1139  
1140      WIN32_FIND_DATAW file_data;
1141      HANDLE hFind;
1142 @@ -1122,7 +1182,10 @@ int mbedtls_x509_crt_parse_path( mbedtls_x509_crt *chain, const char *path )
1143      p = filename + len;
1144      filename[len++] = '*';
1145  
1146 -    w_ret = MultiByteToWideChar( CP_ACP, 0, filename, len, szDir,
1147 +    if ( FAILED ( SizeTToInt( len, &lengthAsInt ) ) )
1148 +        return( MBEDTLS_ERR_X509_FILE_IO_ERROR );
1149 +
1150 +    w_ret = MultiByteToWideChar( CP_ACP, 0, filename, lengthAsInt, szDir,
1151                                   MAX_PATH - 3 );
1152      if( w_ret == 0 )
1153          return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
1154 @@ -1139,8 +1202,11 @@ int mbedtls_x509_crt_parse_path( mbedtls_x509_crt *chain, const char *path )
1155          if( file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
1156              continue;
1157  
1158 +        if ( FAILED( SizeTToInt( wcslen( file_data.cFileName ), &lengthAsInt ) ) )
1159 +            return( MBEDTLS_ERR_X509_FILE_IO_ERROR );
1160 +
1161          w_ret = WideCharToMultiByte( CP_ACP, 0, file_data.cFileName,
1162 -                                     lstrlenW( file_data.cFileName ),
1163 +                                     lengthAsInt,
1164                                       p, (int) len - 1,
1165                                       NULL, NULL );
1166          if( w_ret == 0 )
1167 @@ -1219,6 +1285,98 @@ cleanup:
1168  }
1169  #endif /* MBEDTLS_FS_IO */
1170  
1171 +#if defined(MBEDTLS_X509_EXPANDED_SUBJECT_ALT_NAME_SUPPORT)
1172 +static const char x509_directory_name_label[] = "directoryName=(";
1173 +static const char x509_directory_name_epilogue[] = ")";
1174 +
1175 +/* Length of label constant excluding terminating null. */
1176 +#define LABEL_LEN( label ) ( sizeof ( label ) - 1 )
1177 +
1178 +static int x509_info_subject_alt_name( char **buf, size_t *size,
1179 +                                       const mbedtls_x509_general_names *subject_alt_name )
1180 +{
1181 +    int ret;
1182 +    size_t i;
1183 +    size_t n = *size;
1184 +    char *p = *buf;
1185 +    const mbedtls_x509_general_names *cur = subject_alt_name;
1186 +    const char *sep = "";
1187 +    size_t sep_len = 0;
1188 +
1189 +    while( cur != NULL )
1190 +    {
1191 +        switch ( cur->general_name.name_type )
1192 +        {
1193 +        case MBEDTLS_X509_GENERALNAME_DNSNAME:
1194 +            i = cur->general_name.dns_name.len + sep_len;
1195 +
1196 +            if( i >= n )
1197 +            {
1198 +                *p = '\0';
1199 +                return( MBEDTLS_ERR_X509_BUFFER_TOO_SMALL );
1200 +            }
1201 +
1202 +            n -= i;
1203 +            for( i = 0; i < sep_len; i++ )
1204 +                *p++ = sep[i];
1205 +            for( i = 0; i < cur->general_name.dns_name.len; i++ )
1206 +                *p++ = cur->general_name.dns_name.p[i];
1207 +
1208 +            break;
1209 +
1210 +        case MBEDTLS_X509_GENERALNAME_DIRECTORYNAME:
1211 +            i = sep_len + LABEL_LEN( x509_directory_name_label );
1212 +            if( i >= n )
1213 +            {
1214 +                *p = '\0';
1215 +                return( MBEDTLS_ERR_X509_BUFFER_TOO_SMALL );
1216 +            }
1217 +
1218 +            n -= i;
1219 +            for( i = 0; i < sep_len; i++ )
1220 +                *p++ = sep[i];
1221 +            for( i = 0; i < LABEL_LEN( x509_directory_name_label ); i++ )
1222 +                *p++ = x509_directory_name_label[i];
1223 +
1224 +            ret = mbedtls_x509_dn_gets( p, n, cur->general_name.directory_name );
1225 +            if( ret < 0 || ( (size_t) ret ) >= n )
1226 +            {
1227 +                *p = '\0';
1228 +                return( MBEDTLS_ERR_X509_BUFFER_TOO_SMALL );
1229 +            }
1230 +
1231 +            n -= ret;
1232 +            p += ret;
1233 +
1234 +            i = LABEL_LEN( x509_directory_name_epilogue );
1235 +
1236 +            if( i >= n )
1237 +            {
1238 +                *p = '\0';
1239 +                return( MBEDTLS_ERR_X509_BUFFER_TOO_SMALL );
1240 +            }
1241 +
1242 +            n -= i;
1243 +            for( i = 0; i < LABEL_LEN( x509_directory_name_epilogue ); i++ )
1244 +                *p++ = x509_directory_name_epilogue[i];
1245 +
1246 +            break;
1247 +        }
1248 +
1249 +        sep = ", ";
1250 +        sep_len = 2;
1251 +
1252 +        cur = cur->next;
1253 +    }
1254 +
1255 +    *p = '\0';
1256 +
1257 +    *size = n;
1258 +    *buf = p;
1259 +
1260 +    return( 0 );
1261 +}
1262 +#else
1263  static int x509_info_subject_alt_name( char **buf, size_t *size,
1264                                         const mbedtls_x509_sequence *subject_alt_name )
1265  {
1266 @@ -1256,6 +1414,7 @@ static int x509_info_subject_alt_name( char **buf, size_t *size,
1267  
1268      return( 0 );
1269  }
1270 +#endif
1271  
1272  #define PRINT_ITEM(i)                           \
1273      {                                           \
1274 @@ -2188,7 +2347,11 @@ int mbedtls_x509_crt_verify_with_profile( mbedtls_x509_crt *crt,
1275      int pathlen = 0, selfsigned = 0;
1276      mbedtls_x509_crt *parent;
1277      mbedtls_x509_name *name;
1278 +#if defined(MBEDTLS_X509_EXPANDED_SUBJECT_ALT_NAME_SUPPORT)
1279 +    mbedtls_x509_general_names *cur = NULL;
1280 +#else
1281      mbedtls_x509_sequence *cur = NULL;
1282 +#endif
1283      mbedtls_pk_type_t pk_type;
1284  
1285      if( profile == NULL )
1286 @@ -2207,6 +2370,22 @@ int mbedtls_x509_crt_verify_with_profile( mbedtls_x509_crt *crt,
1287  
1288              while( cur != NULL )
1289              {
1290 +#if defined(MBEDTLS_X509_EXPANDED_SUBJECT_ALT_NAME_SUPPORT)
1291 +                /* Only consider dNSName subject alternative names for this check; ignore other types. */
1292 +                if ( cur->general_name.name_type == MBEDTLS_X509_GENERALNAME_DNSNAME )
1293 +                {
1294 +                    if ( cur->general_name.dns_name.len == cn_len &&
1295 +                        x509_memcasecmp( cn, cur->general_name.dns_name.p, cn_len ) == 0 )
1296 +                        break;
1297 +
1298 +                    if ( cur->general_name.dns_name.len > 2 &&
1299 +                        memcmp( cur->general_name.dns_name.p, "*.", 2 ) == 0 &&
1300 +                        x509_check_wildcard( cn, &cur->general_name.dns_name ) == 0 )
1301 +                    {
1302 +                        break;
1303 +                    }
1304 +                }
1305 +#else
1306                  if( cur->buf.len == cn_len &&
1307                      x509_memcasecmp( cn, cur->buf.p, cn_len ) == 0 )
1308                      break;
1309 @@ -2217,6 +2396,7 @@ int mbedtls_x509_crt_verify_with_profile( mbedtls_x509_crt *crt,
1310                  {
1311                      break;
1312                  }
1313 +#endif
1314  
1315                  cur = cur->next;
1316              }
1317 @@ -2318,6 +2498,10 @@ void mbedtls_x509_crt_free( mbedtls_x509_crt *crt )
1318      mbedtls_x509_crt *cert_prv;
1319      mbedtls_x509_name *name_cur;
1320      mbedtls_x509_name *name_prv;
1321 +#if defined(MBEDTLS_X509_EXPANDED_SUBJECT_ALT_NAME_SUPPORT)
1322 +    mbedtls_x509_general_names *san_cur;
1323 +    mbedtls_x509_general_names *san_prv;
1324 +#endif
1325      mbedtls_x509_sequence *seq_cur;
1326      mbedtls_x509_sequence *seq_prv;
1327  
1328 @@ -2359,6 +2543,38 @@ void mbedtls_x509_crt_free( mbedtls_x509_crt *crt )
1329              mbedtls_free( seq_prv );
1330          }
1331  
1332 +#if defined(MBEDTLS_X509_EXPANDED_SUBJECT_ALT_NAME_SUPPORT)
1333 +        if ( cert_cur->subject_alt_names.general_name.name_type == MBEDTLS_X509_GENERALNAME_DIRECTORYNAME )
1334 +        {
1335 +            name_cur = cert_cur->subject_alt_names.general_name.directory_name;
1336 +            while ( name_cur != NULL )
1337 +            {
1338 +                name_prv = name_cur;
1339 +                name_cur = name_cur->next;
1340 +                mbedtls_zeroize( name_prv, sizeof( mbedtls_x509_name ) );
1341 +                mbedtls_free( name_prv );
1342 +            }
1343 +        }
1344 +        san_cur = cert_cur->subject_alt_names.next;
1345 +        while ( san_cur != NULL )
1346 +        {
1347 +            san_prv = san_cur;
1348 +            san_cur = san_cur->next;
1349 +            if ( san_prv->general_name.name_type == MBEDTLS_X509_GENERALNAME_DIRECTORYNAME )
1350 +            {
1351 +                name_cur = san_prv->general_name.directory_name;
1352 +                while ( name_cur != NULL )
1353 +                {
1354 +                    name_prv = name_cur;
1355 +                    name_cur = name_cur->next;
1356 +                    mbedtls_zeroize( name_prv, sizeof( mbedtls_x509_name ) );
1357 +                    mbedtls_free( name_prv );
1358 +                }
1359 +            }
1360 +            mbedtls_zeroize( san_prv, sizeof( mbedtls_x509_general_names ));
1361 +            mbedtls_free( san_prv );
1362 +        }
1363 +#else
1364          seq_cur = cert_cur->subject_alt_names.next;
1365          while( seq_cur != NULL )
1366          {
1367 @@ -2367,6 +2583,7 @@ void mbedtls_x509_crt_free( mbedtls_x509_crt *crt )
1368              mbedtls_zeroize( seq_prv, sizeof( mbedtls_x509_sequence ) );
1369              mbedtls_free( seq_prv );
1370          }
1371 +#endif
1372  
1373          if( cert_cur->raw.p != NULL )
1374          {
1375 diff --git a/library/x509write_crt.c b/library/x509write_crt.c
1376 index d1d9a22..55f194d 100644
1377 --- a/library/x509write_crt.c
1378 +++ b/library/x509write_crt.c
1379 @@ -263,6 +263,63 @@ int mbedtls_x509write_crt_set_ns_cert_type( mbedtls_x509write_cert *ctx,
1380      return( 0 );
1381  }
1382  
1383 +#if defined(MBEDTLS_X509_EXPANDED_SUBJECT_ALT_NAME_SUPPORT)
1384 +static int x509write_crt_set_subject_alt_name( unsigned char **c, unsigned char *buf,
1385 +                                               const mbedtls_x509_general_name *name )
1386 +{
1387 +    int ret;
1388 +    size_t len = 0;
1389 +
1390 +    switch ( name->name_type )
1391 +    {
1392 +    case MBEDTLS_X509_GENERALNAME_DNSNAME:
1393 +        MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( c, buf, name->dns_name.p, name->dns_name.len ) );
1394 +        MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( c, buf, name->dns_name.len ) );
1395 +        MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( c, buf, MBEDTLS_ASN1_CONTEXT_SPECIFIC | 2 ) );
1396 +        break;
1397 +
1398 +    case MBEDTLS_X509_GENERALNAME_DIRECTORYNAME:
1399 +        MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_names( c, buf, name->directory_name ) );
1400 +        MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( c, buf, len ) );
1401 +        MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( c, buf,
1402 +                                   MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 4 ) );
1403 +        break;
1404 +
1405 +    default:
1406 +        return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
1407 +    }
1408 +
1409 +    return( (int)len );
1410 +}
1411 +
1412 +int mbedtls_x509write_crt_set_subject_alt_names( mbedtls_x509write_cert *ctx,
1413 +                                                 const mbedtls_x509_general_names *names )
1414 +{
1415 +    int ret;
1416 +    unsigned char buf[2048];
1417 +    unsigned char *c = buf + sizeof( buf );
1418 +    size_t len = 0;
1419 +    const mbedtls_x509_general_names *cur;
1420 +
1421 +    for ( cur = names; cur != NULL; cur = cur->next )
1422 +    {
1423 +        MBEDTLS_ASN1_CHK_ADD( len, x509write_crt_set_subject_alt_name( &c, buf, &cur->general_name ) );
1424 +    }
1425 +
1426 +    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
1427 +    MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) );
1428 +
1429 +    ret = mbedtls_x509write_crt_set_extension( ctx, MBEDTLS_OID_SUBJECT_ALT_NAME,
1430 +                                               MBEDTLS_OID_SIZE( MBEDTLS_OID_SUBJECT_ALT_NAME ),
1431 +                                               0, c, len );
1432 +
1433 +    if( ret != 0 )
1434 +        return( ret );
1435 +
1436 +    return( 0 );
1437 +}
1438 +#endif /* MBEDTLS_X509_EXPANDED_SUBJECT_ALT_NAME_SUPPORT */
1439 +
1440  static int x509_write_time( unsigned char **p, unsigned char *start,
1441                              const char *time, size_t size )
1442  {
1443 diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
1444 index a1d71e1..b334656 100644
1445 --- a/programs/ssl/ssl_client2.c
1446 +++ b/programs/ssl/ssl_client2.c
1447 @@ -58,6 +58,7 @@ int main( void )
1448  #include "mbedtls/error.h"
1449  #include "mbedtls/debug.h"
1450  #include "mbedtls/timing.h"
1451 +#include "mbedtls/oid.h"
1452  
1453  #include <stdio.h>
1454  #include <stdlib.h>
1455 @@ -103,6 +104,8 @@ int main( void )
1456  #define DFL_FALLBACK            -1
1457  #define DFL_EXTENDED_MS         -1
1458  #define DFL_ETM                 -1
1459 +#define DFL_EKU_CLIENT          ""
1460 +#define DFL_EKU_SERVER          ""
1461  
1462  #define GET_REQUEST "GET %s HTTP/1.0\r\nExtra-header: "
1463  #define GET_REQUEST_END "\r\n\r\n"
1464 @@ -222,6 +225,14 @@ int main( void )
1465  #define USAGE_ECJPAKE ""
1466  #endif
1467  
1468 +#if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE)
1469 +#define USAGE_EKU \
1470 +    "    eku=%%s-%%s           default: client-server\n"          \
1471 +    "                        options for each: server, client, codesign\n"
1472 +#else
1473 +#define USAGE_EKU ""
1474 +#endif
1475 +
1476  #define USAGE \
1477      "\n usage: ssl_client2 param=<>...\n"                   \
1478      "\n acceptable parameters:\n"                           \
1479 @@ -261,6 +272,7 @@ int main( void )
1480      USAGE_ETM                                               \
1481      USAGE_RECSPLIT                                          \
1482      USAGE_DHMLEN                                            \
1483 +    USAGE_EKU                                               \
1484      "\n"                                                    \
1485      "    arc4=%%d             default: (library default: 0)\n" \
1486      "    min_version=%%s      default: (library default: tls1)\n"       \
1487 @@ -317,6 +329,10 @@ struct options
1488      int fallback;               /* is this a fallback connection?           */
1489      int extended_ms;            /* negotiate extended master secret?        */
1490      int etm;                    /* negotiate encrypt then mac?              */
1491 +    const char *eku_cli;        /* EKU to check for in client cert          */
1492 +    size_t eku_cli_len;         /* length of eku_cli                        */
1493 +    const char *eku_srv;        /* EKU to check for in server cert          */
1494 +    size_t eku_srv_len;         /* length of eku_srv                        */
1495  } opt;
1496  
1497  static void my_debug( void *ctx, int level,
1498 @@ -507,6 +523,10 @@ int main( int argc, char *argv[] )
1499      opt.fallback            = DFL_FALLBACK;
1500      opt.extended_ms         = DFL_EXTENDED_MS;
1501      opt.etm                 = DFL_ETM;
1502 +    opt.eku_cli             = DFL_EKU_CLIENT;
1503 +    opt.eku_cli_len         = MBEDTLS_OID_SIZE( DFL_EKU_CLIENT );
1504 +    opt.eku_srv             = DFL_EKU_SERVER;
1505 +    opt.eku_srv_len         = MBEDTLS_OID_SIZE( DFL_EKU_SERVER );
1506  
1507      for( i = 1; i < argc; i++ )
1508      {
1509 @@ -797,6 +817,47 @@ int main( int argc, char *argv[] )
1510              if( opt.dhmlen < 0 )
1511                  goto usage;
1512          }
1513 +        else if ( strcmp(p, "eku") == 0 )
1514 +        {
1515 +            if ( ( p = strchr( q, '-' ) ) == NULL )
1516 +                goto usage;
1517 +            *p++ = '\0';
1518 +            if ( strcmp( q, "server" ) == 0 )
1519 +            {
1520 +                opt.eku_cli = MBEDTLS_OID_SERVER_AUTH;
1521 +                opt.eku_cli_len = MBEDTLS_OID_SIZE(MBEDTLS_OID_SERVER_AUTH);
1522 +            }
1523 +            else if ( strcmp( q, "client" ) == 0 )
1524 +            {
1525 +                opt.eku_cli = MBEDTLS_OID_CLIENT_AUTH;
1526 +                opt.eku_cli_len = MBEDTLS_OID_SIZE(MBEDTLS_OID_CLIENT_AUTH);
1527 +            }
1528 +            else if ( strcmp( q, "codesign" ) == 0 )
1529 +            {
1530 +                opt.eku_cli = MBEDTLS_OID_CODE_SIGNING;
1531 +                opt.eku_cli_len = MBEDTLS_OID_SIZE(MBEDTLS_OID_CODE_SIGNING);
1532 +            }
1533 +            else
1534 +                goto usage;
1535 +
1536 +            if ( strcmp( p, "server" ) == 0 )
1537 +            {
1538 +                opt.eku_srv = MBEDTLS_OID_SERVER_AUTH;
1539 +                opt.eku_srv_len = MBEDTLS_OID_SIZE(MBEDTLS_OID_SERVER_AUTH);
1540 +            }
1541 +            else if ( strcmp( p, "client" ) == 0 )
1542 +            {
1543 +                opt.eku_srv = MBEDTLS_OID_CLIENT_AUTH;
1544 +                opt.eku_srv_len = MBEDTLS_OID_SIZE(MBEDTLS_OID_CLIENT_AUTH);
1545 +            }
1546 +            else if ( strcmp( p, "codesign" ) == 0 )
1547 +            {
1548 +                opt.eku_srv = MBEDTLS_OID_CODE_SIGNING;
1549 +                opt.eku_srv_len = MBEDTLS_OID_SIZE(MBEDTLS_OID_CODE_SIGNING);
1550 +            }
1551 +            else
1552 +                goto usage;
1553 +        }
1554          else
1555              goto usage;
1556      }
1557 @@ -1088,6 +1149,19 @@ int main( int argc, char *argv[] )
1558          goto exit;
1559      }
1560  
1561 +#if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE)
1562 +    if ( opt.eku_cli_len > 0 && opt.eku_srv_len > 0 )
1563 +    {
1564 +        if( ( ret = mbedtls_ssl_conf_ekus( &conf,
1565 +                        opt.eku_cli, opt.eku_cli_len,
1566 +                        opt.eku_srv, opt.eku_srv_len ) ) != 0 )
1567 +        {
1568 +            mbedtls_printf( " failed\n  ! mbedtls_ssl_config_ekus returned -0x%x\n\n", -ret );
1569 +            goto exit;
1570 +        }
1571 +    }
1572 +#endif
1573 +
1574  #if defined(MBEDTLS_X509_CRT_PARSE_C)
1575      if( opt.debug_level > 0 )
1576          mbedtls_ssl_conf_verify( &conf, my_verify, NULL );
1577 diff --git a/programs/ssl/ssl_server2.c b/programs/ssl/ssl_server2.c
1578 index 18bda59..e65576b 100644
1579 --- a/programs/ssl/ssl_server2.c
1580 +++ b/programs/ssl/ssl_server2.c
1581 @@ -59,6 +59,7 @@ int main( void )
1582  #include "mbedtls/error.h"
1583  #include "mbedtls/debug.h"
1584  #include "mbedtls/timing.h"
1585 +#include "mbedtls/oid.h"
1586  
1587  #include <stdio.h>
1588  #include <stdlib.h>
1589 @@ -136,6 +137,8 @@ int main( void )
1590  #define DFL_BADMAC_LIMIT        -1
1591  #define DFL_EXTENDED_MS         -1
1592  #define DFL_ETM                 -1
1593 +#define DFL_EKU_CLIENT          ""
1594 +#define DFL_EKU_SERVER          ""
1595  
1596  #define LONG_RESPONSE "<p>01-blah-blah-blah-blah-blah-blah-blah-blah-blah\r\n" \
1597      "02-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah-blah\r\n"  \
1598 @@ -304,6 +307,14 @@ int main( void )
1599  #define USAGE_ECJPAKE ""
1600  #endif
1601  
1602 +#if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE)
1603 +#define USAGE_EKU \
1604 +    "    eku=%%s-%%s           default: client-server\n"          \
1605 +    "                        options for each: server, client, codesign\n"
1606 +#else
1607 +#define USAGE_EKU ""
1608 +#endif
1609 +
1610  #define USAGE \
1611      "\n usage: ssl_server2 param=<>...\n"                   \
1612      "\n acceptable parameters:\n"                           \
1613 @@ -338,6 +349,7 @@ int main( void )
1614      USAGE_ALPN                                              \
1615      USAGE_EMS                                               \
1616      USAGE_ETM                                               \
1617 +    USAGE_EKU                                               \
1618      "\n"                                                    \
1619      "    arc4=%%d             default: (library default: 0)\n" \
1620      "    min_version=%%s      default: (library default: tls1)\n"       \
1621 @@ -400,6 +412,10 @@ struct options
1622      uint32_t hs_to_min;         /* Initial value of DTLS handshake timer    */
1623      uint32_t hs_to_max;         /* Max value of DTLS handshake timer        */
1624      int badmac_limit;           /* Limit of records with bad MAC            */
1625 +    const char *eku_cli;        /* EKU to check for in client cert          */
1626 +    size_t eku_cli_len;         /* length of eku_cli                        */
1627 +    const char *eku_srv;        /* EKU to check for in server cert          */
1628 +    size_t eku_srv_len;         /* length of eku_srv                        */
1629  } opt;
1630  
1631  static void my_debug( void *ctx, int level,
1632 @@ -943,6 +959,10 @@ int main( int argc, char *argv[] )
1633      opt.badmac_limit        = DFL_BADMAC_LIMIT;
1634      opt.extended_ms         = DFL_EXTENDED_MS;
1635      opt.etm                 = DFL_ETM;
1636 +    opt.eku_cli             = DFL_EKU_CLIENT;
1637 +    opt.eku_cli_len         = MBEDTLS_OID_SIZE( DFL_EKU_CLIENT );
1638 +    opt.eku_srv             = DFL_EKU_SERVER;
1639 +    opt.eku_srv_len         = MBEDTLS_OID_SIZE( DFL_EKU_SERVER );
1640  
1641      for( i = 1; i < argc; i++ )
1642      {
1643 @@ -1232,6 +1252,47 @@ int main( int argc, char *argv[] )
1644          {
1645              opt.sni = q;
1646          }
1647 +        else if( strcmp( p, "eku" ) == 0 )
1648 +        {
1649 +            if( ( p = strchr( q, '-' ) ) == NULL )
1650 +                goto usage;
1651 +            *p++ = '\0';
1652 +            if( strcmp( q, "server" ) == 0 )
1653 +            {
1654 +                opt.eku_cli = MBEDTLS_OID_SERVER_AUTH;
1655 +                opt.eku_cli_len = MBEDTLS_OID_SIZE( MBEDTLS_OID_SERVER_AUTH );
1656 +            }
1657 +            else if( strcmp( q, "client" ) == 0 )
1658 +            {
1659 +                opt.eku_cli = MBEDTLS_OID_CLIENT_AUTH;
1660 +                opt.eku_cli_len = MBEDTLS_OID_SIZE( MBEDTLS_OID_CLIENT_AUTH );
1661 +            }
1662 +            else if( strcmp( q, "codesign" ) == 0 )
1663 +            {
1664 +                opt.eku_cli = MBEDTLS_OID_CODE_SIGNING;
1665 +                opt.eku_cli_len = MBEDTLS_OID_SIZE( MBEDTLS_OID_CODE_SIGNING );
1666 +            }
1667 +            else
1668 +                goto usage;
1669 +
1670 +            if( strcmp( p, "server" ) == 0 )
1671 +            {
1672 +                opt.eku_srv = MBEDTLS_OID_SERVER_AUTH;
1673 +                opt.eku_srv_len = MBEDTLS_OID_SIZE( MBEDTLS_OID_SERVER_AUTH );
1674 +            }
1675 +            else if( strcmp( p, "client" ) == 0 )
1676 +            {
1677 +                opt.eku_srv = MBEDTLS_OID_CLIENT_AUTH;
1678 +                opt.eku_srv_len = MBEDTLS_OID_SIZE( MBEDTLS_OID_CLIENT_AUTH );
1679 +            }
1680 +            else if( strcmp( p, "codesign" ) == 0 )
1681 +            {
1682 +                opt.eku_srv = MBEDTLS_OID_CODE_SIGNING;
1683 +                opt.eku_srv_len = MBEDTLS_OID_SIZE( MBEDTLS_OID_CODE_SIGNING );
1684 +            }
1685 +            else
1686 +                goto usage;
1687 +        }
1688          else
1689              goto usage;
1690      }
1691 @@ -1608,6 +1669,20 @@ int main( int argc, char *argv[] )
1692          goto exit;
1693      }
1694  
1695 +#if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE)
1696 +    if ( opt.eku_cli_len > 0 && opt.eku_srv_len > 0 )
1697 +    {
1698 +        if( ( ret = mbedtls_ssl_conf_ekus( &conf,
1699 +                        opt.eku_cli, opt.eku_cli_len,
1700 +                        opt.eku_srv, opt.eku_srv_len ) ) != 0 )
1701 +        {
1702 +            mbedtls_printf( " failed\n  ! mbedtls_ssl_config_ekus returned -0x%x\n\n", -ret );
1703 +            goto exit;
1704 +        }
1705 +    }
1706 +#endif
1707 +
1708 +
1709      if( opt.auth_mode != DFL_AUTH_MODE )
1710          mbedtls_ssl_conf_authmode( &conf, opt.auth_mode );
1711  
1712 diff --git a/programs/x509/cert_write.c b/programs/x509/cert_write.c
1713 index 66e5f1d..1405e71 100644
1714 --- a/programs/x509/cert_write.c
1715 +++ b/programs/x509/cert_write.c
1716 @@ -66,6 +66,16 @@ int main( void )
1717  #define USAGE_CSR ""
1718  #endif /* MBEDTLS_X509_CSR_PARSE_C */
1719  
1720 +#if defined(MBEDTLS_X509_EXPANDED_SUBJECT_ALT_NAME_SUPPORT)
1721 +#define USAGE_SUBJ_ALT_NAME \
1722 +    "    subj_alt_name=%%s    default: (empty)\n"       \
1723 +    "                        Comma-separated-list of values:\n"      \
1724 +    "                          dns_name=%%s\n"          \
1725 +    "                          directory_name=(OU=%%s;CN=%%s;...)\n"
1726 +#else
1727 +#define USAGE_SUBJ_ALT_NAME ""
1728 +#endif /* MBEDTLS_X509_EXPANDED_SUBJECT_ALT_NAME_SUPPORT */
1729 +
1730  #define DFL_ISSUER_CRT          ""
1731  #define DFL_REQUEST_FILE        ""
1732  #define DFL_SUBJECT_KEY         "subject.key"
1733 @@ -127,6 +137,7 @@ int main( void )
1734      "                          ssl_ca\n"                \
1735      "                          email_ca\n"              \
1736      "                          object_signing_ca\n"     \
1737 +    USAGE_SUBJ_ALT_NAME                                 \
1738      "\n"
1739  
1740  /*
1741 @@ -151,6 +162,9 @@ struct options
1742      int max_pathlen;            /* maximum CA path length               */
1743      unsigned char key_usage;    /* key usage flags                      */
1744      unsigned char ns_cert_type; /* NS cert type                         */
1745 +#if defined(MBEDTLS_X509_EXPANDED_SUBJECT_ALT_NAME_SUPPORT)
1746 +    mbedtls_x509_general_names subj_alt_names; /* Subject alternative names  */
1747 +#endif
1748  } opt;
1749  
1750  int write_certificate( mbedtls_x509write_cert *crt, const char *output_file,
1751 @@ -182,6 +196,58 @@ int write_certificate( mbedtls_x509write_cert *crt, const char *output_file,
1752      return( 0 );
1753  }
1754  
1755 +#if defined(MBEDTLS_X509_EXPANDED_SUBJECT_ALT_NAME_SUPPORT)
1756 +static int add_subj_alt_name( mbedtls_x509_general_names **cur, const mbedtls_x509_general_name *add )
1757 +{
1758 +    mbedtls_x509_general_names *new_cur = *cur;
1759 +
1760 +    if ( new_cur->general_name.name_type != 0 )
1761 +    {
1762 +        if (new_cur->next != NULL)
1763 +            return( -1 );
1764 +
1765 +        new_cur->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_general_names ) );
1766 +
1767 +        if (new_cur->next == NULL)
1768 +            return( -1 );
1769 +
1770 +        new_cur = new_cur->next;
1771 +    }
1772 +
1773 +    memcpy( &new_cur->general_name, add, sizeof( mbedtls_x509_general_name ) );
1774 +
1775 +    *cur = new_cur;
1776 +
1777 +    return( 0 );
1778 +}
1779 +
1780 +static void subj_alt_names_free( mbedtls_x509_general_names *names )
1781 +{
1782 +    mbedtls_x509_general_names *cur = names;
1783 +    mbedtls_x509_general_names *prv;
1784 +
1785 +    while ( cur != NULL )
1786 +    {
1787 +        prv = cur;
1788 +        cur = cur->next;
1789 +
1790 +        if ( prv->general_name.name_type == MBEDTLS_X509_GENERALNAME_DIRECTORYNAME )
1791 +        {
1792 +            mbedtls_asn1_free_named_data_list( &prv->general_name.directory_name );
1793 +        }
1794 +
1795 +        /*
1796 +         * The first node is part of the opt struct and not heap allocated, so don't free it.
1797 +         * Every other loop, free the node.
1798 +         */
1799 +        if ( prv != names )
1800 +        {
1801 +            mbedtls_free( prv );
1802 +        }
1803 +    }
1804 +}
1805 +#endif
1806 +
1807  int main( int argc, char *argv[] )
1808  {
1809      int ret = 0;
1810 @@ -202,6 +268,10 @@ int main( int argc, char *argv[] )
1811      mbedtls_entropy_context entropy;
1812      mbedtls_ctr_drbg_context ctr_drbg;
1813      const char *pers = "crt example app";
1814 +#if defined(MBEDTLS_X509_EXPANDED_SUBJECT_ALT_NAME_SUPPORT)
1815 +    mbedtls_x509_general_names *name_cur = &opt.subj_alt_names;
1816 +    mbedtls_x509_general_name name_tmp;
1817 +#endif
1818  
1819      /*
1820       * Set to sane values
1821 @@ -243,6 +313,9 @@ int main( int argc, char *argv[] )
1822      opt.max_pathlen         = DFL_MAX_PATHLEN;
1823      opt.key_usage           = DFL_KEY_USAGE;
1824      opt.ns_cert_type        = DFL_NS_CERT_TYPE;
1825 +#if defined(MBEDTLS_X509_EXPANDED_SUBJECT_ALT_NAME_SUPPORT)
1826 +    memset( &opt.subj_alt_names, 0, sizeof( opt.subj_alt_names ) );
1827 +#endif
1828  
1829      for( i = 1; i < argc; i++ )
1830      {
1831 @@ -358,6 +431,86 @@ int main( int argc, char *argv[] )
1832                  q = r;
1833              }
1834          }
1835 +#if defined(MBEDTLS_X509_EXPANDED_SUBJECT_ALT_NAME_SUPPORT)
1836 +        else if( strcmp( p, "subj_alt_name" ) == 0 )
1837 +        {
1838 +            while( q != NULL )
1839 +            {
1840 +                char *s;
1841 +
1842 +                if( ( r = strchr( q, ',' ) ) != NULL )
1843 +                    *r++ = '\0';
1844 +
1845 +                if( ( s = strchr( q, '=' ) ) == NULL )
1846 +                    goto usage;
1847 +
1848 +                *s++ = '\0';
1849 +
1850 +                if( strcmp( q, "dns_name" ) == 0 )
1851 +                {
1852 +                    name_tmp.name_type = MBEDTLS_X509_GENERALNAME_DNSNAME;
1853 +                    name_tmp.dns_name.len = strlen( s );
1854 +                    name_tmp.dns_name.p = (unsigned char *)s;
1855 +                    /* tag field doesn't need to be set for writing. */
1856 +                }
1857 +                else if( strcmp( q, "directory_name" ) == 0 )
1858 +                {
1859 +                    char *rp, *tmp;
1860 +
1861 +                    if ( *s != '(' )
1862 +                        goto usage;
1863 +
1864 +                    if ( ( rp = strchr( s + 1, ')' ) ) == NULL )
1865 +                        goto usage;
1866 +
1867 +                    /*
1868 +                     * Replace semicolons in the parenthesized list with commas and temporarily
1869 +                     * terminate with null so we can use mbedtls_x509_string_to_names, call it,
1870 +                     * and then change them back so the commas don't interfere with later parsing.
1871 +                     */
1872 +
1873 +                    for ( tmp = s + 1; tmp < rp; tmp++ )
1874 +                    {
1875 +                        if ( *tmp == ';' )
1876 +                        {
1877 +                            *tmp = ',';
1878 +                        }
1879 +                    }
1880 +
1881 +                    *rp = '\0';
1882 +
1883 +                    name_tmp.name_type = MBEDTLS_X509_GENERALNAME_DIRECTORYNAME;
1884 +                    name_tmp.directory_name = NULL;
1885 +                    ret = mbedtls_x509_string_to_names( &name_tmp.directory_name, s + 1 );
1886 +
1887 +                    if ( ret < 0 )
1888 +                    {
1889 +                        mbedtls_strerror( ret, buf, 1024 );
1890 +                        mbedtls_printf( " failed\n  ! mbedtls_x509_string_to_names returned %d - %s\n", ret, buf );
1891 +                        goto exit;
1892 +                    }
1893 +
1894 +                    for ( tmp = s + 1; tmp < rp; tmp++ )
1895 +                    {
1896 +                        if ( *tmp == ',' )
1897 +                        {
1898 +                            *tmp = ';';
1899 +                        }
1900 +                    }
1901 +
1902 +                    *rp = ')';
1903 +
1904 +                }
1905 +                else
1906 +                    goto usage;
1907 +
1908 +                if ( add_subj_alt_name( &name_cur, &name_tmp ) != 0 )
1909 +                    goto exit;
1910 +
1911 +                q = r;
1912 +            }
1913 +        }
1914 +#endif /* MBEDTLS_X509_EXPANDED_SUBJECT_ALT_NAME_SUPPORT */
1915          else
1916              goto usage;
1917      }
1918 @@ -632,6 +785,24 @@ int main( int argc, char *argv[] )
1919          mbedtls_printf( " ok\n" );
1920      }
1921  
1922 +#if defined(MBEDTLS_X509_EXPANDED_SUBJECT_ALT_NAME_SUPPORT)
1923 +    if ( opt.subj_alt_names.general_name.name_type )
1924 +    {
1925 +        mbedtls_printf( "  . Adding the Subject Alternative Name extension ..." );
1926 +        fflush( stdout );
1927 +
1928 +        ret = mbedtls_x509write_crt_set_subject_alt_names( &crt, &opt.subj_alt_names );
1929 +        if ( ret != 0 )
1930 +        {
1931 +            mbedtls_strerror( ret, buf, 1024 );
1932 +            mbedtls_printf( " failed\n  !  mbedtls_x509write_crt_set_subject_alt_names returned -0x%02x - %s\n\n", -ret, buf );
1933 +            goto exit;
1934 +        }
1935 +
1936 +        mbedtls_printf( " ok\n" );
1937 +    }
1938 +#endif
1939 +
1940      /*
1941       * 1.2. Writing the request
1942       */
1943 @@ -649,6 +820,9 @@ int main( int argc, char *argv[] )
1944      mbedtls_printf( " ok\n" );
1945  
1946  exit:
1947 +#if defined(MBEDTLS_X509_EXPANDED_SUBJECT_ALT_NAME_SUPPORT)
1948 +    subj_alt_names_free( &opt.subj_alt_names );
1949 +#endif
1950      mbedtls_x509write_crt_free( &crt );
1951      mbedtls_pk_free( &loaded_subject_key );
1952      mbedtls_pk_free( &loaded_issuer_key );
1953 diff --git a/tests/data_files/server1-bothnames.crt b/tests/data_files/server1-bothnames.crt
1954 new file mode 100644
1955 index 0000000..b7e1f40
1956 --- /dev/null
1957 +++ b/tests/data_files/server1-bothnames.crt
1958 @@ -0,0 +1,22 @@
1959 +-----BEGIN CERTIFICATE-----
1960 +MIIDoTCCAomgAwIBAgIBATANBgkqhkiG9w0BAQsFADA7MQswCQYDVQQGEwJOTDER
1961 +MA8GA1UEChMIUG9sYXJTU0wxGTAXBgNVBAMTEFBvbGFyU1NMIFRlc3QgQ0EwHhcN
1962 +MTEwMjEyMTQ0NDA2WhcNMjEwMjEyMTQ0NDA2WjA8MQswCQYDVQQGEwJOTDERMA8G
1963 +A1UEChMIUG9sYXJTU0wxGjAYBgNVBAMTEVBvbGFyU1NMIFNlcnZlciAxMIIBIjAN
1964 +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqQIfPUBq1VVTi/027oJlLhVhXom/
1965 +uOhFkNvuiBZS0/FDUEeWEllkh2v9K+BG+XO+3c+S4ZFb7Wagb4kpeUWA0INq1UFD
1966 +d185fAkER4KwVzlw7aPsFRkeqDMIR8EFQqn9TMO0390GH00QUUBncxMPQPhtgSVf
1967 +CrFTxjB+FTms+Vruf5KepgVb5xOXhbUjktnUJAbVCSWJdQfdphqPPwkZvq1lLGTr
1968 +lZvc/kFeF6babFtpzAK6FCwWJJxK3M3Q91Jnc/EtoCP9fvQxyi1wyokLBNsupk9w
1969 +bp7OvViJ4lNZnm5akmXiiD8MlBmj3eXonZUT7Snbq3AS3FrKaxerUoJUsQIDAQAB
1970 +o4GuMIGrMAkGA1UdEwQCMAAwHQYDVR0OBBYEFB901j8pwXR0RTsFEiw9qL1DWQKm
1971 +MB8GA1UdIwQYMBaAFLRa5KWz3tJS9rnVppUP6z68x/3/MF4GA1UdEQRXMFWkPzA9
1972 +MQswCQYDVQQGEwJOTDERMA8GA1UEChMIUG9sYXJTU0wxGzAZBgNVBAMTElBvbGFy
1973 +U1NMIFNlcnZlciAxQYISb3RoZXIucG9sYXJzc2wub3JnMA0GCSqGSIb3DQEBCwUA
1974 +A4IBAQCUqTN1WjWPMNpflyDTOEq+DEbNgj83ghhB6cCxHCGNT12CpBvQDh4bj5QC
1975 +c77x8kN5fwy+HO1QIwHhBtjLC0IUfKvJUaTbwvIDH1NotrxSg/ft3HG/ijbTrX9/
1976 +kxDXDcHkOlNX4Y5cJnU7UBm81n7WInGvGqperXTIDgW5CEkQp2ErtxvSZkNtYe82
1977 +0DwVIQwjbF5hxFxQPGEzM1AANMyzOYKNtg6S7ElbtU4NQqvcBNr3vaG5ipMrkf2u
1978 +kfJZAs+bPo+UyuFBCRGmOMgOAUrK4WvvxtqKFZDdty+pyTiR25x55Upfum7jxeBt
1979 +Nnu2TUYcY472fXbZA5Y7/gGnmmRe
1980 +-----END CERTIFICATE-----
1981 diff --git a/tests/data_files/server1-directoryname.crt b/tests/data_files/server1-directoryname.crt
1982 new file mode 100644
1983 index 0000000..b220230
1984 --- /dev/null
1985 +++ b/tests/data_files/server1-directoryname.crt
1986 @@ -0,0 +1,22 @@
1987 +-----BEGIN CERTIFICATE-----
1988 +MIIDjTCCAnWgAwIBAgIBATANBgkqhkiG9w0BAQsFADA7MQswCQYDVQQGEwJOTDER
1989 +MA8GA1UEChMIUG9sYXJTU0wxGTAXBgNVBAMTEFBvbGFyU1NMIFRlc3QgQ0EwHhcN
1990 +MTEwMjEyMTQ0NDA2WhcNMjEwMjEyMTQ0NDA2WjA8MQswCQYDVQQGEwJOTDERMA8G
1991 +A1UEChMIUG9sYXJTU0wxGjAYBgNVBAMTEVBvbGFyU1NMIFNlcnZlciAxMIIBIjAN
1992 +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqQIfPUBq1VVTi/027oJlLhVhXom/
1993 +uOhFkNvuiBZS0/FDUEeWEllkh2v9K+BG+XO+3c+S4ZFb7Wagb4kpeUWA0INq1UFD
1994 +d185fAkER4KwVzlw7aPsFRkeqDMIR8EFQqn9TMO0390GH00QUUBncxMPQPhtgSVf
1995 +CrFTxjB+FTms+Vruf5KepgVb5xOXhbUjktnUJAbVCSWJdQfdphqPPwkZvq1lLGTr
1996 +lZvc/kFeF6babFtpzAK6FCwWJJxK3M3Q91Jnc/EtoCP9fvQxyi1wyokLBNsupk9w
1997 +bp7OvViJ4lNZnm5akmXiiD8MlBmj3eXonZUT7Snbq3AS3FrKaxerUoJUsQIDAQAB
1998 +o4GaMIGXMAkGA1UdEwQCMAAwHQYDVR0OBBYEFB901j8pwXR0RTsFEiw9qL1DWQKm
1999 +MB8GA1UdIwQYMBaAFLRa5KWz3tJS9rnVppUP6z68x/3/MEoGA1UdEQRDMEGkPzA9
2000 +MQswCQYDVQQGEwJOTDERMA8GA1UEChMIUG9sYXJTU0wxGzAZBgNVBAMTElBvbGFy
2001 +U1NMIFNlcnZlciAxQTANBgkqhkiG9w0BAQsFAAOCAQEAYb6K1UU+6eUdfMD/vayr
2002 +36VEOFd2SA2AxBgj2GKAB7IyKgT6bZTo6SyfJWtvWlp7Ofjc9nQ2iObNRqN1499t
2003 +DmAb3IM9yXuG00GVVg5brC3RtX1w4KJci2z+R2FX+HPAJW5E2rlU7OIm0FfF2aV6
2004 +0qhHeJSCwi8DkS6U6dQW3vmFXf4sEVtyRkY5Zh3pEcSb3mNpvxNdq1Ro8TRmOGHe
2005 +HrHAWxgBTeUJ0Dv/TNn39FNyvzwvWDFFxhwgs4+43N7FuSM6XUA86mkwLAsrjfWx
2006 +fKNjq7fpJX2dS08ISV/RismU6RGt/TW4PXrtvEIfy1+kaMDSt+ffz1C1cuSen7xz
2007 +6w==
2008 +-----END CERTIFICATE-----
2009 diff --git a/tests/data_files/server1-dnsname.crt b/tests/data_files/server1-dnsname.crt
2010 new file mode 100644
2011 index 0000000..f3bad52
2012 --- /dev/null
2013 +++ b/tests/data_files/server1-dnsname.crt
2014 @@ -0,0 +1,21 @@
2015 +-----BEGIN CERTIFICATE-----
2016 +MIIDXjCCAkagAwIBAgIBATANBgkqhkiG9w0BAQsFADA7MQswCQYDVQQGEwJOTDER
2017 +MA8GA1UEChMIUG9sYXJTU0wxGTAXBgNVBAMTEFBvbGFyU1NMIFRlc3QgQ0EwHhcN
2018 +MTEwMjEyMTQ0NDA2WhcNMjEwMjEyMTQ0NDA2WjA8MQswCQYDVQQGEwJOTDERMA8G
2019 +A1UEChMIUG9sYXJTU0wxGjAYBgNVBAMTEVBvbGFyU1NMIFNlcnZlciAxMIIBIjAN
2020 +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqQIfPUBq1VVTi/027oJlLhVhXom/
2021 +uOhFkNvuiBZS0/FDUEeWEllkh2v9K+BG+XO+3c+S4ZFb7Wagb4kpeUWA0INq1UFD
2022 +d185fAkER4KwVzlw7aPsFRkeqDMIR8EFQqn9TMO0390GH00QUUBncxMPQPhtgSVf
2023 +CrFTxjB+FTms+Vruf5KepgVb5xOXhbUjktnUJAbVCSWJdQfdphqPPwkZvq1lLGTr
2024 +lZvc/kFeF6babFtpzAK6FCwWJJxK3M3Q91Jnc/EtoCP9fvQxyi1wyokLBNsupk9w
2025 +bp7OvViJ4lNZnm5akmXiiD8MlBmj3eXonZUT7Snbq3AS3FrKaxerUoJUsQIDAQAB
2026 +o2wwajAJBgNVHRMEAjAAMB0GA1UdDgQWBBQfdNY/KcF0dEU7BRIsPai9Q1kCpjAf
2027 +BgNVHSMEGDAWgBS0WuSls97SUva51aaVD+s+vMf9/zAdBgNVHREEFjAUghJvdGhl
2028 +ci5wb2xhcnNzbC5vcmcwDQYJKoZIhvcNAQELBQADggEBAFTQDT3BP8qKss7yVjZM
2029 +8RkFF9GuqgCYPWyyuixzxYU5OJzzo/g5ZQ37wfcOMIUA7Ygs0Pv/L0n5PzncJqwO
2030 +mJpQRghbI4yp2qVsKpdx+SVTS9aDm/madjREbSzk/tXVskINbuaWQ/azKbB6MReu
2031 +XXgcw/iROpKJl+WCVr0cy6EAWPd3QBNLYyoAKpMQT2HXfQT/AhEZJINSYrkJeHCt
2032 +BgTGq8tvXE2OtcjTcmp+KIpkXA6A0laRx5up1xET9wDrdll5AEhXSXDzIEOwIBhJ
2033 +3cExQNdWbO6JdjBi5Qaoq9o7ItQOFSTM6PvRC3MYRwN+WhFdb+4Kmvd5oIArRaHo
2034 +MEM=
2035 +-----END CERTIFICATE-----
2036 diff --git a/tests/data_files/server11-directoryname.crt b/tests/data_files/server11-directoryname.crt
2037 new file mode 100644
2038 index 0000000..d9e0a16
2039 --- /dev/null
2040 +++ b/tests/data_files/server11-directoryname.crt
2041 @@ -0,0 +1,10 @@
2042 +-----BEGIN CERTIFICATE-----
2043 +MIIBVzCB/qADAgECAgkAkWvgYjFeWV0wCgYIKoZIzj0EAwIwEzERMA8GA1UEAwwI
2044 +VGVzdENlcnQwHhcNMTYxMjEzMjMwNDM3WhcNMzAwODIyMjMwNDM3WjATMREwDwYD
2045 +VQQDDAhUZXN0Q2VydDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABOkrKfbStoGN
2046 +oOUTet2ryyRul++FE++6vpEup83bHywiOO1a4JtDgzNJcjj8/uAKsECYQrI1T4Y/
2047 +rpnYu8ff9VGjOzA5MDcGA1UdEQQwMC6kLDAqMRYwFAYDVQQLDA1OYW1lIEFzc2ln
2048 +bmVyMRAwDgYDVQQDDAdNeSBSb2xlMAoGCCqGSM49BAMCA0gAMEUCIGdd/GGuoOXJ
2049 +8Ipl3hy69gb35MmkwEQKuYrud+Qs5XfFAiEAsmEOP4KFZadL23XJfMfGuPn2MDLr
2050 +G9lDDpiediVxGO0=
2051 +-----END CERTIFICATE-----
2052 diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh
2053 index 57155b8..7e754bb 100755
2054 --- a/tests/ssl-opt.sh
2055 +++ b/tests/ssl-opt.sh
2056 @@ -2526,6 +2526,16 @@ run_test    "extKeyUsage cli: codeSign -> fail" \
2057              -c "Processing of the Certificate handshake message failed" \
2058              -C "Ciphersuite is TLS-"
2059  
2060 +run_test    "extKeyUsage cli: codeSign(requested) -> OK " \
2061 +            "$O_SRV -key data_files/server5.key \
2062 +             -cert data_files/server5.eku-cs.crt" \
2063 +            "$P_CLI debug_level=1 eku=client-codesign" \
2064 +            0 \
2065 +            -C "bad certificate (usage extensions)" \
2066 +            -C "Processing of the Certificate handshake message failed" \
2067 +            -c "Ciphersuite is TLS-"
2068 +
2069 +
2070  # Tests for extendedKeyUsage, part 3: server-side checking of client cert
2071  
2072  run_test    "extKeyUsage cli-auth: clientAuth -> OK" \
2073 @@ -2568,6 +2578,14 @@ run_test    "extKeyUsage cli-auth: codeSign -> fail (hard)" \
2074              -s "bad certificate (usage extensions)" \
2075              -s "Processing of the Certificate handshake message failed"
2076  
2077 +run_test    "extKeyUsage cli-auth: codeSign(requested) -> OK" \
2078 +            "$P_SRV debug_level=1 auth_mode=required eku=codesign-server" \
2079 +            "$O_CLI -key data_files/server5.key \
2080 +             -cert data_files/server5.eku-cs.crt" \
2081 +            0 \
2082 +            -S "bad certificate (usage extensions)" \
2083 +            -S "Processing of the Certificate handshake message failed"
2084 +
2085  # Tests for DHM parameters loading
2086  
2087  run_test    "DHM parameters: reference" \
2088 diff --git a/tests/suites/test_suite_x509parse.data b/tests/suites/test_suite_x509parse.data
2089 index c829823..30fff78 100644
2090 --- a/tests/suites/test_suite_x509parse.data
2091 +++ b/tests/suites/test_suite_x509parse.data
2092 @@ -122,6 +122,22 @@ X509 certificate v1 with extension
2093  depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3:MBEDTLS_SHA1_C
2094  x509_cert_info:"data_files/cert_v1_with_ext.crt":"cert. version     \: 1\nserial number     \: BD\:ED\:44\:C7\:D2\:3E\:C2\:A4\nissuer name       \: C=XX, ST=XX, L=XX, O=XX, OU=XX, emailAddress=admin@identity-check.org, CN=identity-check.org\nsubject name      \: C=XX, ST=XX, L=XX, O=XX, OU=XX, emailAddress=admin@identity-check.org, CN=identity-check.org\nissued  on        \: 2013-07-04 16\:17\:02\nexpires on        \: 2014-07-04 16\:17\:02\nsigned using      \: RSA with SHA1\nRSA key size      \: 2048 bits\nsubject alt name  \: identity-check.org, www.identity-check.org\n"
2095  
2096 +X509 Certificate information EC directoryName subjectAltName
2097 +depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_SHA256_C:MBEDTLS_X509_EXPANDED_SUBJECT_ALT_NAME_SUPPORT
2098 +x509_cert_info:"data_files/server11-directoryname.crt":"cert. version     \: 3\nserial number     \: 91\:6B\:E0\:62\:31\:5E\:59\:5D\nissuer name       \: CN=TestCert\nsubject name      \: CN=TestCert\nissued  on        \: 2016-12-13 23\:04\:37\nexpires on        \: 2030-08-22 23\:04\:37\nsigned using      \: ECDSA with SHA256\nEC key size       \: 256 bits\nsubject alt name  \: directoryName=(OU=Name Assigner, CN=My Role)\n"
2099 +
2100 +X509 Certificate information dNSName subjectAltName
2101 +depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_SHA256_C:MBEDTLS_X509_EXPANDED_SUBJECT_ALT_NAME_SUPPORT
2102 +x509_cert_info:"data_files/server1-dnsname.crt":"cert. version     \: 3\nserial number     \: 01\nissuer name       \: C=NL, O=PolarSSL, CN=PolarSSL Test CA\nsubject name      \: C=NL, O=PolarSSL, CN=PolarSSL Server 1\nissued  on        \: 2011-02-12 14\:44\:06\nexpires on        \: 2021-02-12 14\:44\:06\nsigned using      \: RSA with SHA-256\nRSA key size      \: 2048 bits\nbasic constraints \: CA=false\nsubject alt name  \: other.polarssl.org\n"
2103 +
2104 +X509 Certificate information directoryName subjectAltName
2105 +depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_SHA256_C:MBEDTLS_X509_EXPANDED_SUBJECT_ALT_NAME_SUPPORT
2106 +x509_cert_info:"data_files/server1-directoryname.crt":"cert. version     \: 3\nserial number     \: 01\nissuer name       \: C=NL, O=PolarSSL, CN=PolarSSL Test CA\nsubject name      \: C=NL, O=PolarSSL, CN=PolarSSL Server 1\nissued  on        \: 2011-02-12 14\:44\:06\nexpires on        \: 2021-02-12 14\:44\:06\nsigned using      \: RSA with SHA-256\nRSA key size      \: 2048 bits\nbasic constraints \: CA=false\nsubject alt name  \: directoryName=(C=NL, O=PolarSSL, CN=PolarSSL Server 1A)\n"
2107 +
2108 +X509 Certificate information dNSName+directoryName subjectAltName
2109 +depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_SHA256_C:MBEDTLS_X509_EXPANDED_SUBJECT_ALT_NAME_SUPPORT
2110 +x509_cert_info:"data_files/server1-bothnames.crt":"cert. version     \: 3\nserial number     \: 01\nissuer name       \: C=NL, O=PolarSSL, CN=PolarSSL Test CA\nsubject name      \: C=NL, O=PolarSSL, CN=PolarSSL Server 1\nissued  on        \: 2011-02-12 14\:44\:06\nexpires on        \: 2021-02-12 14\:44\:06\nsigned using      \: RSA with SHA-256\nRSA key size      \: 2048 bits\nbasic constraints \: CA=false\nsubject alt name  \: directoryName=(C=NL, O=PolarSSL, CN=PolarSSL Server 1A), other.polarssl.org\n"
2111 +
2112  X509 CRL information #1
2113  depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_SHA1_C
2114  mbedtls_x509_crl_info:"data_files/crl_expired.pem":"CRL version   \: 1\nissuer name   \: C=NL, O=PolarSSL, CN=PolarSSL Test CA\nthis update   \: 2011-02-20 10\:24\:19\nnext update   \: 2011-02-20 11\:24\:19\nRevoked certificates\:\nserial number\: 01 revocation date\: 2011-02-12 14\:44\:07\nserial number\: 03 revocation date\: 2011-02-12 14\:44\:07\nsigned using  \: RSA with SHA1\n"
2115 diff --git a/tests/suites/test_suite_x509write.data b/tests/suites/test_suite_x509write.data
2116 index d4d2a98..57c2ad2 100644
2117 --- a/tests/suites/test_suite_x509write.data
2118 +++ b/tests/suites/test_suite_x509write.data
2119 @@ -58,6 +58,18 @@ Certificate write check Server1 SHA1, version 1
2120  depends_on:MBEDTLS_SHA1_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_MD5_C
2121  x509_crt_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"1":"20110212144406":"20210212144406":MBEDTLS_MD_SHA1:0:0:MBEDTLS_X509_CRT_VERSION_1:"data_files/server1.v1.crt"
2122  
2123 +Certificate write check Server1 SHA256 with dNSName
2124 +depends_on:MBEDTLS_SHA1_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_MD5_C:MBEDTLS_SHA256_C:MBEDTLS_X509_EXPANDED_SUBJECT_ALT_NAME_SUPPORT
2125 +x509_crt_subj_alt_name_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"1":"20110212144406":"20210212144406":MBEDTLS_MD_SHA256:0:0:-1:1:"data_files/server1-dnsname.crt"
2126 +
2127 +Certificate write check Server1 SHA256 with directoryName
2128 +depends_on:MBEDTLS_SHA1_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_MD5_C:MBEDTLS_SHA256_C:MBEDTLS_X509_EXPANDED_SUBJECT_ALT_NAME_SUPPORT
2129 +x509_crt_subj_alt_name_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"1":"20110212144406":"20210212144406":MBEDTLS_MD_SHA256:0:0:-1:2:"data_files/server1-directoryname.crt"
2130 +
2131 +Certificate write check Server1 SHA256 with dNSName and directoryName
2132 +depends_on:MBEDTLS_SHA1_C:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_DES_C:MBEDTLS_CIPHER_MODE_CBC:MBEDTLS_MD5_C:MBEDTLS_SHA256_C:MBEDTLS_X509_EXPANDED_SUBJECT_ALT_NAME_SUPPORT
2133 +x509_crt_subj_alt_name_check:"data_files/server1.key":"":"C=NL,O=PolarSSL,CN=PolarSSL Server 1":"data_files/test-ca.key":"PolarSSLTest":"C=NL,O=PolarSSL,CN=PolarSSL Test CA":"1":"20110212144406":"20210212144406":MBEDTLS_MD_SHA256:0:0:-1:3:"data_files/server1-bothnames.crt"
2134 +
2135  X509 String to Names #1
2136  mbedtls_x509_string_to_names:"C=NL,O=Offspark\, Inc., OU=PolarSSL":"C=NL, O=Offspark, Inc., OU=PolarSSL":0
2137  
2138 diff --git a/tests/suites/test_suite_x509write.function b/tests/suites/test_suite_x509write.function
2139 index 89be31f..184ac2c 100644
2140 --- a/tests/suites/test_suite_x509write.function
2141 +++ b/tests/suites/test_suite_x509write.function
2142 @@ -157,6 +157,131 @@ exit:
2143  }
2144  /* END_CASE */
2145  
2146 +/* BEGIN_CASE depends_on:MBEDTLS_PEM_WRITE_C:MBEDTLS_X509_CRT_WRITE_C:MBEDTLS_SHA1_C:MBEDTLS_X509_EXPANDED_SUBJECT_ALT_NAME_SUPPORT */
2147 +void x509_crt_subj_alt_name_check( char *subject_key_file, char *subject_pwd,
2148 +                                   char *subject_name, char *issuer_key_file,
2149 +                                   char *issuer_pwd, char *issuer_name,
2150 +                                   char *serial_str, char *not_before, char *not_after,
2151 +                                   int md_type, int key_usage, int cert_type, int ver, int subj_alt_names_type,
2152 +                                   char *cert_check_file )
2153 +{
2154 +    mbedtls_pk_context subject_key, issuer_key;
2155 +    mbedtls_x509write_cert crt;
2156 +    unsigned char buf[4096];
2157 +    unsigned char check_buf[5000];
2158 +    mbedtls_mpi serial;
2159 +    int ret;
2160 +    size_t olen = 0, pem_len = 0;
2161 +    int der_len = -1;
2162 +    FILE *f;
2163 +    rnd_pseudo_info rnd_info;
2164 +
2165 +    memset( &rnd_info, 0x2a, sizeof( rnd_pseudo_info ) );
2166 +    mbedtls_mpi_init( &serial );
2167 +    mbedtls_pk_init( &subject_key );
2168 +    mbedtls_pk_init( &issuer_key );
2169 +
2170 +    TEST_ASSERT( mbedtls_pk_parse_keyfile( &subject_key, subject_key_file,
2171 +                                         subject_pwd ) == 0 );
2172 +    TEST_ASSERT( mbedtls_pk_parse_keyfile( &issuer_key, issuer_key_file,
2173 +                                         issuer_pwd ) == 0 );
2174 +    TEST_ASSERT( mbedtls_mpi_read_string( &serial, 10, serial_str ) == 0 );
2175 +
2176 +    mbedtls_x509write_crt_init( &crt );
2177 +    if( ver != -1 )
2178 +        mbedtls_x509write_crt_set_version( &crt, ver );
2179 +    TEST_ASSERT( mbedtls_x509write_crt_set_serial( &crt, &serial ) == 0 );
2180 +    TEST_ASSERT( mbedtls_x509write_crt_set_validity( &crt, not_before,
2181 +                                                   not_after ) == 0 );
2182 +    mbedtls_x509write_crt_set_md_alg( &crt, md_type );
2183 +    TEST_ASSERT( mbedtls_x509write_crt_set_issuer_name( &crt, issuer_name ) == 0 );
2184 +    TEST_ASSERT( mbedtls_x509write_crt_set_subject_name( &crt, subject_name ) == 0 );
2185 +    mbedtls_x509write_crt_set_subject_key( &crt, &subject_key );
2186 +    mbedtls_x509write_crt_set_issuer_key( &crt, &issuer_key );
2187 +
2188 +    if( crt.version >= MBEDTLS_X509_CRT_VERSION_3 )
2189 +    {
2190 +        TEST_ASSERT( mbedtls_x509write_crt_set_basic_constraints( &crt, 0, 0 ) == 0 );
2191 +        TEST_ASSERT( mbedtls_x509write_crt_set_subject_key_identifier( &crt ) == 0 );
2192 +        TEST_ASSERT( mbedtls_x509write_crt_set_authority_key_identifier( &crt ) == 0 );
2193 +        if( key_usage != 0 )
2194 +            TEST_ASSERT( mbedtls_x509write_crt_set_key_usage( &crt, key_usage ) == 0 );
2195 +        if( cert_type != 0 )
2196 +            TEST_ASSERT( mbedtls_x509write_crt_set_ns_cert_type( &crt, cert_type ) == 0 );
2197 +        if( subj_alt_names_type != 0 )
2198 +        {
2199 +            mbedtls_x509_general_names dns_name, directory_name;
2200 +            mbedtls_x509_general_names *first = NULL;
2201 +
2202 +            memset( &dns_name, 0, sizeof( dns_name ) );
2203 +            memset( &directory_name, 0, sizeof( directory_name ) );
2204 +
2205 +            if ( ( subj_alt_names_type & 1 ) == 1 )
2206 +            {
2207 +                dns_name.general_name.name_type = MBEDTLS_X509_GENERALNAME_DNSNAME;
2208 +                /* Nothing will try to modify the memory pointed to by p, so this cast is safe. */
2209 +                dns_name.general_name.dns_name.p = (unsigned char *) "other.polarssl.org";
2210 +                dns_name.general_name.dns_name.len = strlen( (const char *) dns_name.general_name.dns_name.p );
2211 +                first = &dns_name;
2212 +            }
2213 +
2214 +            if ( ( subj_alt_names_type & 2 ) == 2 )
2215 +            {
2216 +                directory_name.general_name.name_type = MBEDTLS_X509_GENERALNAME_DIRECTORYNAME;
2217 +                TEST_ASSERT( mbedtls_x509_string_to_names( &directory_name.general_name.directory_name, "C=NL,O=PolarSSL,CN=PolarSSL Server 1A" ) == 0 );
2218 +                if ( first == NULL )
2219 +                {
2220 +                    first = &directory_name;
2221 +                }
2222 +                else
2223 +                {
2224 +                    first->next = &directory_name;
2225 +                }
2226 +            }
2227 +
2228 +            TEST_ASSERT( mbedtls_x509write_crt_set_subject_alt_names( &crt, first ) == 0 );
2229 +
2230 +            if ( ( subj_alt_names_type & 2 ) == 2 )
2231 +            {
2232 +                mbedtls_asn1_free_named_data_list( &directory_name.general_name.directory_name );
2233 +            }
2234 +        }
2235 +    }
2236 +
2237 +    ret = mbedtls_x509write_crt_pem( &crt, buf, sizeof(buf),
2238 +                             rnd_pseudo_rand, &rnd_info );
2239 +    TEST_ASSERT( ret == 0 );
2240 +
2241 +    pem_len = strlen( (char *) buf );
2242 +
2243 +    f = fopen( cert_check_file, "r" );
2244 +    TEST_ASSERT( f != NULL );
2245 +    olen = fread( check_buf, 1, sizeof(check_buf), f );
2246 +    fclose( f );
2247 +    TEST_ASSERT( olen < sizeof(check_buf) );
2248 +
2249 +    TEST_ASSERT( olen >= pem_len - 1 );
2250 +    TEST_ASSERT( memcmp( buf, check_buf, pem_len - 1 ) == 0 );
2251 +
2252 +    der_len = mbedtls_x509write_crt_der( &crt, buf, sizeof( buf ),
2253 +                            rnd_pseudo_rand, &rnd_info );
2254 +    TEST_ASSERT( der_len >= 0 );
2255 +
2256 +    if( der_len == 0 )
2257 +        goto exit;
2258 +
2259 +    ret = mbedtls_x509write_crt_der( &crt, buf, (size_t)( der_len - 1 ),
2260 +                            rnd_pseudo_rand, &rnd_info );
2261 +    TEST_ASSERT( ret == MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
2262 +
2263 +exit:
2264 +    mbedtls_x509write_crt_free( &crt );
2265 +    mbedtls_pk_free( &issuer_key );
2266 +    mbedtls_pk_free( &subject_key );
2267 +    mbedtls_mpi_free( &serial );
2268 +}
2269 +/* END_CASE */
2270 +
2271  /* BEGIN_CASE depends_on:MBEDTLS_X509_CREATE_C:MBEDTLS_X509_USE_C */
2272  void mbedtls_x509_string_to_names( char *name, char *parsed_name, int result )
2273  {