summaryrefslogtreecommitdiffstats
path: root/meta/recipes-support/curl/curl/CVE-2021-22924.patch
blob: 68fde45ddf1165c0269eb9a94f94ae24aefac1ef (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
Subject: [PATCH] vtls: fix connection reuse checks for issuer cert and
 case sensitivity CVE-2021-22924

Reported-by: Harry Sintonen
Bug: https://curl.se/docs/CVE-2021-22924.html
CVE: CVE-2021-22924
Upstream-Status: backport from Ubuntu curl_7.68.0-1ubuntu2.6
Signed-off-by: Mike Crowe <mac@mcrowe.com>
---
 lib/url.c          |  5 +++--
 lib/urldata.h      |  2 +-
 lib/vtls/gtls.c    | 10 +++++-----
 lib/vtls/nss.c     |  4 ++--
 lib/vtls/openssl.c | 12 ++++++------
 lib/vtls/vtls.c    | 23 ++++++++++++++++++-----
 6 files changed, 35 insertions(+), 21 deletions(-)

diff --git a/lib/url.c b/lib/url.c
index 47fc66aed..eebad8d32 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -3555,6 +3555,9 @@ static CURLcode create_conn(struct Curl_easy *data,
   data->set.proxy_ssl.primary.CApath = data->set.str[STRING_SSL_CAPATH_PROXY];
   data->set.ssl.primary.CAfile = data->set.str[STRING_SSL_CAFILE_ORIG];
   data->set.proxy_ssl.primary.CAfile = data->set.str[STRING_SSL_CAFILE_PROXY];
+  data->set.ssl.primary.issuercert = data->set.str[STRING_SSL_ISSUERCERT_ORIG];
+  data->set.proxy_ssl.primary.issuercert =
+    data->set.str[STRING_SSL_ISSUERCERT_PROXY];
   data->set.ssl.primary.random_file = data->set.str[STRING_SSL_RANDOM_FILE];
   data->set.proxy_ssl.primary.random_file =
     data->set.str[STRING_SSL_RANDOM_FILE];
@@ -3575,8 +3578,6 @@ static CURLcode create_conn(struct Curl_easy *data,
 
   data->set.ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE_ORIG];
   data->set.proxy_ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE_PROXY];
-  data->set.ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT_ORIG];
-  data->set.proxy_ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT_PROXY];
   data->set.ssl.cert = data->set.str[STRING_CERT_ORIG];
   data->set.proxy_ssl.cert = data->set.str[STRING_CERT_PROXY];
   data->set.ssl.cert_type = data->set.str[STRING_CERT_TYPE_ORIG];
diff --git a/lib/urldata.h b/lib/urldata.h
index fbb8b645e..615fbf369 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -224,6 +224,7 @@ struct ssl_primary_config {
   long version_max;      /* max supported version the client wants to use*/
   char *CApath;          /* certificate dir (doesn't work on windows) */
   char *CAfile;          /* certificate to verify peer against */
+  char *issuercert;      /* optional issuer certificate filename */
   char *clientcert;
   char *random_file;     /* path to file containing "random" data */
   char *egdsocket;       /* path to file containing the EGD daemon socket */
@@ -240,7 +241,6 @@ struct ssl_config_data {
   struct ssl_primary_config primary;
   long certverifyresult; /* result from the certificate verification */
   char *CRLfile;   /* CRL to check certificate revocation */
-  char *issuercert;/* optional issuer certificate filename */
   curl_ssl_ctx_callback fsslctx; /* function to initialize ssl ctx */
   void *fsslctxp;        /* parameter for call back */
   char *cert; /* client certificate file name */
diff --git a/lib/vtls/gtls.c b/lib/vtls/gtls.c
index 46e149c7d..8c051024f 100644
--- a/lib/vtls/gtls.c
+++ b/lib/vtls/gtls.c
@@ -1059,7 +1059,7 @@ gtls_connect_step3(struct connectdata *conn,
   if(!chainp) {
     if(SSL_CONN_CONFIG(verifypeer) ||
        SSL_CONN_CONFIG(verifyhost) ||
-       SSL_SET_OPTION(issuercert)) {
+       SSL_CONN_CONFIG(issuercert)) {
 #ifdef USE_TLS_SRP
       if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP
          && SSL_SET_OPTION(username) != NULL
@@ -1241,21 +1241,21 @@ gtls_connect_step3(struct connectdata *conn,
        gnutls_x509_crt_t format */
     gnutls_x509_crt_import(x509_cert, chainp, GNUTLS_X509_FMT_DER);
 
-  if(SSL_SET_OPTION(issuercert)) {
+  if(SSL_CONN_CONFIG(issuercert)) {
     gnutls_x509_crt_init(&x509_issuer);
-    issuerp = load_file(SSL_SET_OPTION(issuercert));
+    issuerp = load_file(SSL_CONN_CONFIG(issuercert));
     gnutls_x509_crt_import(x509_issuer, &issuerp, GNUTLS_X509_FMT_PEM);
     rc = gnutls_x509_crt_check_issuer(x509_cert, x509_issuer);
     gnutls_x509_crt_deinit(x509_issuer);
     unload_file(issuerp);
     if(rc <= 0) {
       failf(data, "server certificate issuer check failed (IssuerCert: %s)",
-            SSL_SET_OPTION(issuercert)?SSL_SET_OPTION(issuercert):"none");
+            SSL_CONN_CONFIG(issuercert)?SSL_CONN_CONFIG(issuercert):"none");
       gnutls_x509_crt_deinit(x509_cert);
       return CURLE_SSL_ISSUER_ERROR;
     }
     infof(data, "\t server certificate issuer check OK (Issuer Cert: %s)\n",
-          SSL_SET_OPTION(issuercert)?SSL_SET_OPTION(issuercert):"none");
+          SSL_CONN_CONFIG(issuercert)?SSL_CONN_CONFIG(issuercert):"none");
   }
 
   size = sizeof(certbuf);
diff --git a/lib/vtls/nss.c b/lib/vtls/nss.c
index ef51b0d91..375c78b1b 100644
--- a/lib/vtls/nss.c
+++ b/lib/vtls/nss.c
@@ -2151,9 +2151,9 @@ static CURLcode nss_do_connect(struct connectdata *conn, int sockindex)
   if(result)
     goto error;
 
-  if(SSL_SET_OPTION(issuercert)) {
+  if(SSL_CONN_CONFIG(issuercert)) {
     SECStatus ret = SECFailure;
-    char *nickname = dup_nickname(data, SSL_SET_OPTION(issuercert));
+    char *nickname = dup_nickname(data, SSL_CONN_CONFIG(issuercert));
     if(nickname) {
       /* we support only nicknames in case of issuercert for now */
       ret = check_issuer_cert(BACKEND->handle, nickname);
diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c
index 64f43605a..7e81fd3a0 100644
--- a/lib/vtls/openssl.c
+++ b/lib/vtls/openssl.c
@@ -3547,7 +3547,7 @@ static CURLcode servercert(struct connectdata *conn,
        deallocating the certificate. */
 
     /* e.g. match issuer name with provided issuer certificate */
-    if(SSL_SET_OPTION(issuercert)) {
+    if(SSL_CONN_CONFIG(issuercert)) {
       fp = BIO_new(BIO_s_file());
       if(fp == NULL) {
         failf(data,
@@ -3560,10 +3560,10 @@ static CURLcode servercert(struct connectdata *conn,
         return CURLE_OUT_OF_MEMORY;
       }
 
-      if(BIO_read_filename(fp, SSL_SET_OPTION(issuercert)) <= 0) {
+      if(BIO_read_filename(fp, SSL_CONN_CONFIG(issuercert)) <= 0) {
         if(strict)
           failf(data, "SSL: Unable to open issuer cert (%s)",
-                SSL_SET_OPTION(issuercert));
+                SSL_CONN_CONFIG(issuercert));
         BIO_free(fp);
         X509_free(BACKEND->server_cert);
         BACKEND->server_cert = NULL;
@@ -3574,7 +3574,7 @@ static CURLcode servercert(struct connectdata *conn,
       if(!issuer) {
         if(strict)
           failf(data, "SSL: Unable to read issuer cert (%s)",
-                SSL_SET_OPTION(issuercert));
+                SSL_CONN_CONFIG(issuercert));
         BIO_free(fp);
         X509_free(issuer);
         X509_free(BACKEND->server_cert);
@@ -3585,7 +3585,7 @@ static CURLcode servercert(struct connectdata *conn,
       if(X509_check_issued(issuer, BACKEND->server_cert) != X509_V_OK) {
         if(strict)
           failf(data, "SSL: Certificate issuer check failed (%s)",
-                SSL_SET_OPTION(issuercert));
+                SSL_CONN_CONFIG(issuercert));
         BIO_free(fp);
         X509_free(issuer);
         X509_free(BACKEND->server_cert);
@@ -3594,7 +3594,7 @@ static CURLcode servercert(struct connectdata *conn,
       }
 
       infof(data, " SSL certificate issuer check ok (%s)\n",
-            SSL_SET_OPTION(issuercert));
+            SSL_CONN_CONFIG(issuercert));
       BIO_free(fp);
       X509_free(issuer);
     }
diff --git a/lib/vtls/vtls.c b/lib/vtls/vtls.c
index aaf73ef8f..8c681da14 100644
--- a/lib/vtls/vtls.c
+++ b/lib/vtls/vtls.c
@@ -82,6 +82,16 @@
   else                                       \
     dest->var = NULL;
 
+static bool safecmp(char *a, char *b)
+{
+  if(a && b)
+    return !strcmp(a, b);
+  else if(!a && !b)
+    return TRUE; /* match */
+  return FALSE; /* no match */
+}
+
+
 bool
 Curl_ssl_config_matches(struct ssl_primary_config* data,
                         struct ssl_primary_config* needle)
@@ -91,11 +101,12 @@ Curl_ssl_config_matches(struct ssl_primary_config* data,
      (data->verifypeer == needle->verifypeer) &&
      (data->verifyhost == needle->verifyhost) &&
      (data->verifystatus == needle->verifystatus) &&
-     Curl_safe_strcasecompare(data->CApath, needle->CApath) &&
-     Curl_safe_strcasecompare(data->CAfile, needle->CAfile) &&
-     Curl_safe_strcasecompare(data->clientcert, needle->clientcert) &&
-     Curl_safe_strcasecompare(data->random_file, needle->random_file) &&
-     Curl_safe_strcasecompare(data->egdsocket, needle->egdsocket) &&
+     safecmp(data->CApath, needle->CApath) &&
+     safecmp(data->CAfile, needle->CAfile) &&
+     safecmp(data->issuercert, needle->issuercert) &&
+     safecmp(data->clientcert, needle->clientcert) &&
+     safecmp(data->random_file, needle->random_file) &&
+     safecmp(data->egdsocket, needle->egdsocket) &&
      Curl_safe_strcasecompare(data->cipher_list, needle->cipher_list) &&
      Curl_safe_strcasecompare(data->cipher_list13, needle->cipher_list13) &&
      Curl_safe_strcasecompare(data->pinned_key, needle->pinned_key))
@@ -117,6 +128,7 @@ Curl_clone_primary_ssl_config(struct ssl_primary_config *source,
 
   CLONE_STRING(CApath);
   CLONE_STRING(CAfile);
+  CLONE_STRING(issuercert);
   CLONE_STRING(clientcert);
   CLONE_STRING(random_file);
   CLONE_STRING(egdsocket);
@@ -131,6 +143,7 @@ void Curl_free_primary_ssl_config(struct ssl_primary_config* sslc)
 {
   Curl_safefree(sslc->CApath);
   Curl_safefree(sslc->CAfile);
+  Curl_safefree(sslc->issuercert);
   Curl_safefree(sslc->clientcert);
   Curl_safefree(sslc->random_file);
   Curl_safefree(sslc->egdsocket);
-- 
2.30.2