Update snapshot(2018-01-10)
[platform/upstream/iotivity.git] / extlibs / mbedtls / CVE-2017-14032.patch
1 From e8bd647d8271174d3737dcf68086126b73a73df6 Mon Sep 17 00:00:00 2001
2 From: Oleksii Beketov <ol.beketov@samsung.com>
3 Date: Mon, 18 Dec 2017 15:23:28 +0200
4 Subject: [PATCH] CVE-2017-14032
5
6 Signed-off-by: Oleksii Beketov <ol.beketov@samsung.com>
7 ---
8  include/mbedtls/error.h    |  2 +-
9  include/mbedtls/ssl.h      |  2 +-
10  include/mbedtls/x509.h     |  1 +
11  include/mbedtls/x509_crt.h |  8 +++++++-
12  library/error.c            |  2 ++
13  library/x509_crt.c         | 30 ++++++++++++++++++++++--------
14  6 files changed, 34 insertions(+), 11 deletions(-)
15
16 diff --git a/include/mbedtls/error.h b/include/mbedtls/error.h
17 index 5e549f6..31591e2 100644
18 --- a/include/mbedtls/error.h
19 +++ b/include/mbedtls/error.h
20 @@ -71,7 +71,7 @@
21   * Name      ID  Nr of Errors
22   * PEM       1   9
23   * PKCS#12   1   4 (Started from top)
24 - * X509      2   19
25 + * X509      2   20
26   * PKCS5     2   4 (Started from top)
27   * DHM       3   9
28   * PK        3   14 (Started from top)
29 diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
30 index 495e02c..4f171e0 100644
31 --- a/include/mbedtls/ssl.h
32 +++ b/include/mbedtls/ssl.h
33 @@ -1042,7 +1042,7 @@ void mbedtls_ssl_conf_authmode( mbedtls_ssl_config *conf, int authmode );
34   *
35   *                 If set, the verify callback is called for each
36   *                 certificate in the chain. For implementation
37 - *                 information, please see \c x509parse_verify()
38 + *                 information, please see \c mbedtls_x509_crt_verify()
39   *
40   * \param conf     SSL configuration
41   * \param f_vrfy   verification function
42 diff --git a/include/mbedtls/x509.h b/include/mbedtls/x509.h
43 index f219bf1..128eade 100644
44 --- a/include/mbedtls/x509.h
45 +++ b/include/mbedtls/x509.h
46 @@ -76,6 +76,7 @@
47  #define MBEDTLS_ERR_X509_ALLOC_FAILED                     -0x2880  /**< Allocation of memory failed. */
48  #define MBEDTLS_ERR_X509_FILE_IO_ERROR                    -0x2900  /**< Read/write of file failed. */
49  #define MBEDTLS_ERR_X509_BUFFER_TOO_SMALL                 -0x2980  /**< Destination buffer is too small. */
50 +#define MBEDTLS_ERR_X509_FATAL_ERROR                      -0x3000  /**< A fatal error occured, eg the chain is too long or the vrfy callback failed. */
51  /* \} name */
52  
53  /**
54 diff --git a/include/mbedtls/x509_crt.h b/include/mbedtls/x509_crt.h
55 index 383e484..fd20336 100644
56 --- a/include/mbedtls/x509_crt.h
57 +++ b/include/mbedtls/x509_crt.h
58 @@ -267,7 +267,13 @@ int mbedtls_x509_crt_verify_info( char *buf, size_t size, const char *prefix,
59   *
60   *                 All flags left after returning from the callback
61   *                 are also returned to the application. The function should
62 - *                 return 0 for anything but a fatal error.
63 + *                 return 0 for anything (including invalid certificates)
64 + *                 other than fatal error, as a non-zero return code
65 + *                 immediately aborts the verification process. For fatal
66 + *                 errors, a specific error code should be used (different
67 + *                 from MBEDTLS_ERR_X509_CERT_VERIFY_FAILED which should not
68 + *                 be returned at this point), or MBEDTLS_ERR_X509_FATAL_ERROR
69 + *                 can be used if no better code is available.
70   *
71   * \note           In case verification failed, the results can be displayed
72   *                 using \c mbedtls_x509_crt_verify_info()
73 diff --git a/library/error.c b/library/error.c
74 index dd2db0c..db42381 100644
75 --- a/library/error.c
76 +++ b/library/error.c
77 @@ -480,6 +480,8 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen )
78              mbedtls_snprintf( buf, buflen, "X509 - Read/write of file failed" );
79          if( use_ret == -(MBEDTLS_ERR_X509_BUFFER_TOO_SMALL) )
80              mbedtls_snprintf( buf, buflen, "X509 - Destination buffer is too small" );
81 +        if( use_ret == -(MBEDTLS_ERR_X509_FATAL_ERROR) )
82 +            mbedtls_snprintf( buf, buflen, "X509 - A fatal error occured, eg the chain is too long or the vrfy callback failed" );
83  #endif /* MBEDTLS_X509_USE_C || MBEDTLS_X509_CREATE_C */
84          // END generated code
85  
86 diff --git a/library/x509_crt.c b/library/x509_crt.c
87 index 234f145..1f31a6b 100644
88 --- a/library/x509_crt.c
89 +++ b/library/x509_crt.c
90 @@ -2055,8 +2055,8 @@ static int x509_crt_verify_child(
91      /* path_cnt is 0 for the first intermediate CA */
92      if( 1 + path_cnt > MBEDTLS_X509_MAX_INTERMEDIATE_CA )
93      {
94 -        *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED;
95 -        return( MBEDTLS_ERR_X509_CERT_VERIFY_FAILED );
96 +        /* return immediately as the goal is to avoid unbounded recursion */
97 +        return( MBEDTLS_ERR_X509_FATAL_ERROR );
98      }
99  
100      if( mbedtls_x509_time_is_past( &child->valid_to ) )
101 @@ -2200,11 +2200,14 @@ int mbedtls_x509_crt_verify_with_profile( mbedtls_x509_crt *crt,
102      mbedtls_x509_sequence *cur = NULL;
103      mbedtls_pk_type_t pk_type;
104  
105 -    if( profile == NULL )
106 -        return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
107 -
108      *flags = 0;
109  
110 +    if( profile == NULL )
111 +    {
112 +        ret = MBEDTLS_ERR_X509_BAD_INPUT_DATA;
113 +        goto exit;
114 +    }
115 +
116      if( cn != NULL )
117      {
118          name = &crt->subject;
119 @@ -2278,7 +2281,7 @@ int mbedtls_x509_crt_verify_with_profile( mbedtls_x509_crt *crt,
120          ret = x509_crt_verify_top( crt, parent, ca_crl, profile,
121                                     pathlen, selfsigned, flags, f_vrfy, p_vrfy );
122          if( ret != 0 )
123 -            return( ret );
124 +            goto exit;
125      }
126      else
127      {
128 @@ -2293,17 +2296,28 @@ int mbedtls_x509_crt_verify_with_profile( mbedtls_x509_crt *crt,
129              ret = x509_crt_verify_child( crt, parent, trust_ca, ca_crl, profile,
130                                           pathlen, selfsigned, flags, f_vrfy, p_vrfy );
131              if( ret != 0 )
132 -                return( ret );
133 +                goto exit;
134          }
135          else
136          {
137              ret = x509_crt_verify_top( crt, trust_ca, ca_crl, profile,
138                                         pathlen, selfsigned, flags, f_vrfy, p_vrfy );
139              if( ret != 0 )
140 -                return( ret );
141 +                goto exit;
142          }
143      }
144  
145 +exit:
146 +    /* prevent misuse of the vrfy callback */
147 +    if( ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED )
148 +        ret = MBEDTLS_ERR_X509_FATAL_ERROR;
149 +
150 +    if( ret != 0 )
151 +    {
152 +        *flags = (uint32_t) -1;
153 +        return( ret );
154 +    }
155 +
156      if( *flags != 0 )
157          return( MBEDTLS_ERR_X509_CERT_VERIFY_FAILED );
158  
159 -- 
160 1.9.1
161