aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNatanael Copa <ncopa@alpinelinux.org>2013-05-17 09:40:13 +0000
committerNatanael Copa <ncopa@alpinelinux.org>2013-05-17 09:40:13 +0000
commitca6f0ad926d2fabed66a049927cea2eb176581da (patch)
treef8628a402e4a6f4f81be2b2963724e80c4a92e67
parent8b2da88e8e533e78dfec86f9d1ed4e5cadfa4ca8 (diff)
downloadalpine_aports-ca6f0ad926d2fabed66a049927cea2eb176581da.tar.bz2
alpine_aports-ca6f0ad926d2fabed66a049927cea2eb176581da.tar.xz
alpine_aports-ca6f0ad926d2fabed66a049927cea2eb176581da.zip
main/openswan: securiy fix remote buffer overflow in atodn() (CVE-2013-2053)
patches are from http://libreswan.org/security/CVE-2013-2053/ fixes #1895
-rw-r--r--main/openswan/APKBUILD24
-rw-r--r--main/openswan/CVE-2013-2052.patch346
-rw-r--r--main/openswan/openswan-libreswan-backport-949437-atodn.patch278
-rw-r--r--main/openswan/openswan-libreswan-backport-949437-do_3des.patch61
-rw-r--r--main/openswan/openswan-libreswan-backport-949437-do_aes.patch62
-rw-r--r--main/openswan/openswan-libreswan-backport-949437-x509dn.patch79
6 files changed, 849 insertions, 1 deletions
diff --git a/main/openswan/APKBUILD b/main/openswan/APKBUILD
index 28cc3c2ece..f126798a8a 100644
--- a/main/openswan/APKBUILD
+++ b/main/openswan/APKBUILD
@@ -2,7 +2,7 @@
2# Maintainer: Borys Zhukov <mp5@mp5.im> 2# Maintainer: Borys Zhukov <mp5@mp5.im>
3pkgname=openswan 3pkgname=openswan
4pkgver=2.6.38 4pkgver=2.6.38
5pkgrel=1 5pkgrel=2
6pkgdesc="IPsec Implementation which Allows Building of VPNs" 6pkgdesc="IPsec Implementation which Allows Building of VPNs"
7url="http://www.openswan.org/" 7url="http://www.openswan.org/"
8arch="all" 8arch="all"
@@ -12,6 +12,10 @@ makedepends="gmp-dev bison flex coreutils bash"
12install="" 12install=""
13subpackages="$pkgname-doc" 13subpackages="$pkgname-doc"
14source="http://download.openswan.org/openswan/$pkgname-$pkgver.tar.gz 14source="http://download.openswan.org/openswan/$pkgname-$pkgver.tar.gz
15 openswan-libreswan-backport-949437-atodn.patch
16 openswan-libreswan-backport-949437-do_3des.patch
17 openswan-libreswan-backport-949437-do_aes.patch
18 openswan-libreswan-backport-949437-x509dn.patch
15 ipsec.initd setup.patch" 19 ipsec.initd setup.patch"
16 20
17_builddir="$srcdir"/$pkgname-$pkgver 21_builddir="$srcdir"/$pkgname-$pkgver
@@ -51,5 +55,23 @@ package() {
51 55
52} 56}
53md5sums="13073eb5314b83a31be88e4117e8bbcd openswan-2.6.38.tar.gz 57md5sums="13073eb5314b83a31be88e4117e8bbcd openswan-2.6.38.tar.gz
58500e936c90ad27545d0ab6450fd888aa openswan-libreswan-backport-949437-atodn.patch
596dcfd099ed2cf90231c36ba305e46348 openswan-libreswan-backport-949437-do_3des.patch
60578f171370c373e3501b85de7efc3045 openswan-libreswan-backport-949437-do_aes.patch
61730a94960fe593f12b8d1f4ff9266d2a openswan-libreswan-backport-949437-x509dn.patch
54f019d1fa23627d54462054fedc9de03b ipsec.initd 62f019d1fa23627d54462054fedc9de03b ipsec.initd
55fd3cd27f9da9140fabd935377c3d6921 setup.patch" 63fd3cd27f9da9140fabd935377c3d6921 setup.patch"
64sha256sums="bdd3ccf31df1f3e8530887986ea8b6702a3db139486738213f5de8d8690b3723 openswan-2.6.38.tar.gz
658595019c0ae7e1d00579c8d4ca2ba81b68e3be7b99f099b24e6ea1fd35b2bd7d openswan-libreswan-backport-949437-atodn.patch
6684a5e1c309ff707504a8b2f8ef47865adf6e3d9f0c60f3d1a19c5a8464bdfefb openswan-libreswan-backport-949437-do_3des.patch
67c36316a70d29553995cf89f7b4b2abcf0e05f1e35d725913cae6bfe161bb81a9 openswan-libreswan-backport-949437-do_aes.patch
682390ab47cf5763c832dd9d652ff8ff6766547067502e1719031bac23b977d34a openswan-libreswan-backport-949437-x509dn.patch
6902fd160fb8d64f93a094c9f8a0912ed9cb47789601647f4a72ba3f736b220290 ipsec.initd
706425c491cf1dc366e03e832a1d78bb2846f172ba6fe658b122707157099f9576 setup.patch"
71sha512sums="0963a9df548c901eb562185f97d844f57539668f11fbe2a43712223773053895c761b1d5d0be4fffa64014baf58ff2d7cf23676a3da51c5a5134b0639796ad10 openswan-2.6.38.tar.gz
72c670392e2e9968f0c9269c50858d24b5dc71126c3e066cbca9ceda53b16ad6fe892d4b32a58054a9cdfa14a81553a219098847b8c79ead00b6b8d05dbd18731d openswan-libreswan-backport-949437-atodn.patch
7314e466379a90c01f26997921c7e4967dfc76de1f58f7370e9755e04e1e351b8a7d8fad8b14af3f4a73d3358cc5271e4a89313aad239f12e92ab596c9d7dd0b02 openswan-libreswan-backport-949437-do_3des.patch
743204d412bbd194ab49a6a5d465cbe38c0bc33266d096bc6bcc0cb6d4214fc05505eef0694036f40da4d2b56f9b50950cfe9816f1e4540431b49d859f7fb7e690 openswan-libreswan-backport-949437-do_aes.patch
7505c4a026b8baa91766717a58308cee0415403b1dc0632d805e36da906ec22b91c95b92ee701ca2b6d248f641f124d4ab32ed4fe7f42127aa6e3e308bf170ced3 openswan-libreswan-backport-949437-x509dn.patch
767aefcc624b0e2a50e26f84db6197278c0633eeb38b064c613fbd635cbe606acd1e1280213db7c19f882d809d7eb6ea59a0c47e1b47dfe43de4f1c6deb08d38c4 ipsec.initd
7792152006ef3765c89d28462743bca25ab139c0205187bfb0a2c5992159e390939dc3f5f95c7ccb135d3ad674a756d776b7a7d7db903fd22994cf24478b7a71c8 setup.patch"
diff --git a/main/openswan/CVE-2013-2052.patch b/main/openswan/CVE-2013-2052.patch
new file mode 100644
index 0000000000..a34a67789b
--- /dev/null
+++ b/main/openswan/CVE-2013-2052.patch
@@ -0,0 +1,346 @@
1-----BEGIN PGP SIGNED MESSAGE-----
2Hash: SHA256
3
4commit 7d0ca355a5c7f8337130d4b0b3e7686f2fa4d4c2
5Author: Paul Wouters <pwouters@redhat.com>
6Date: Thu Apr 25 12:44:55 2013 -0400
7
8 * security: atodn() / atoid() buffer overflow
9
10 lib/libswan/x509dn.c:atodn() does not perform any length checking
11 whatsoever on the output buffer.
12
13 Affected:
14 - Libreswan 3.0 and 3.1 (3.2 disabled the oe= option)
15 - Openswan versions up to and including 2.6.38
16 - Possibly certain strongswan 3.x/4.x versions
17
18 This overflow is exposed (pre-authentication) only in opportunistic
19 encryption mode. When it is called via receiving a certificate
20 via IKEv1 or IKEv2, and when it is loaded from disk, the buffers
21 passed to atodn() are big enough.
22
23 This means this vulnerability can only be triggered when:
24 - Opportunistic Encryption is enabled (oe=yes)
25 - The attacker is local in the same network and adds a malicious
26 reverse DNS record to the client's IP, or
27 - The attacker can trigger an OE DNS lookup to a client fully
28 configured with OE and their own key.
29
30 Libreswan and openswan versions do not enable Opportunistic Encryption
31 per default. Most distributions like RHEL, Fedora, Debian and Ubuntu
32 also do not enable OE per default.
33
34 This patch addresses the vulnerability in atodn() and further limits the
35 atoid() call not to traverse into the ASN1 case when triggered by non-cert
36 cases such as opportunistic encryption.
37
38 Vulnerability discoverd by Florian Weimer <fweimer@redhat.com> of the
39 Red Hat Product Security Team.
40
41 Patch by D. Hugh Redelmeier <hugh@mimosa.com> and Paul Wouters <pwouters@redhat.com>
42
43diff --git a/include/asn1.h b/include/asn1.h
44index d69ebf9..b812488 100644
45- --- a/include/asn1.h
46+++ b/include/asn1.h
47@@ -84,8 +84,10 @@ typedef enum {
48 #define ASN1_BODY 0x20
49 #define ASN1_RAW 0x40
50
51- -#define ASN1_INVALID_LENGTH 0xffffffff
52+#define ASN1_INVALID_LENGTH (~(size_t) 0) /* largest size_t */
53
54+#define ASN1_MAX_LEN (1U << (8*3)) /* don't handle objects with length greater than this */
55+#define ASN1_MAX_LEN_LEN 4 /* no coded length takes more than 4 bytes. */
56
57 /* definition of an ASN.1 object */
58
59diff --git a/include/id.h b/include/id.h
60index d1825b4..b440a11 100644
61- --- a/include/id.h
62+++ b/include/id.h
63@@ -47,7 +47,7 @@ extern const struct id *resolve_myid(const struct id *id);
64 extern void set_myFQDN(void);
65 extern void free_myFQDN(void);
66
67- -extern err_t atoid(char *src, struct id *id, bool myid_ok);
68+extern err_t atoid(char *src, struct id *id, bool myid_ok, bool oe_only);
69 extern void iptoid(const ip_address *ip, struct id *id);
70 extern unsigned char* temporary_cyclic_buffer(void);
71 extern int idtoa(const struct id *id, char *dst, size_t dstlen);
72diff --git a/lib/libswan/id.c b/lib/libswan/id.c
73index 4442971..31ca7e5 100644
74- --- a/lib/libswan/id.c
75+++ b/lib/libswan/id.c
76@@ -58,27 +58,29 @@ temporary_cyclic_buffer(void)
77
78 /* Convert textual form of id into a (temporary) struct id.
79 * Note that if the id is to be kept, unshare_id_content will be necessary.
80+ * This function should be split into parts so the boolean arguments can be
81+ * removed -- Paul
82 */
83 err_t
84- -atoid(char *src, struct id *id, bool myid_ok)
85+atoid(char *src, struct id *id, bool myid_ok, bool oe_only)
86 {
87 err_t ugh = NULL;
88
89 *id = empty_id;
90
91- - if (myid_ok && streq("%myid", src))
92+ if (!oe_only && myid_ok && streq("%myid", src))
93 {
94 id->kind = ID_MYID;
95 }
96- - else if (streq("%fromcert", src))
97+ else if (!oe_only && streq("%fromcert", src))
98 {
99 id->kind = ID_FROMCERT;
100 }
101- - else if (streq("%none", src))
102+ else if (!oe_only && streq("%none", src))
103 {
104 id->kind = ID_NONE;
105 }
106- - else if (strchr(src, '=') != NULL)
107+ else if (!oe_only && strchr(src, '=') != NULL)
108 {
109 /* we interpret this as an ASCII X.501 ID_DER_ASN1_DN */
110 id->kind = ID_DER_ASN1_DN;
111@@ -112,7 +114,7 @@ atoid(char *src, struct id *id, bool myid_ok)
112 {
113 if (*src == '@')
114 {
115- - if (*(src+1) == '#')
116+ if (!oe_only && *(src+1) == '#')
117 {
118 /* if there is a second specifier (#) on the line
119 * we interprete this as ID_KEY_ID
120@@ -123,7 +125,7 @@ atoid(char *src, struct id *id, bool myid_ok)
121 ugh = ttodata(src+2, 0, 16, (char *)id->name.ptr
122 , strlen(src), &id->name.len);
123 }
124- - else if (*(src+1) == '~')
125+ else if (!oe_only && *(src+1) == '~')
126 {
127 /* if there is a second specifier (~) on the line
128 * we interprete this as a binary ID_DER_ASN1_DN
129@@ -134,7 +136,7 @@ atoid(char *src, struct id *id, bool myid_ok)
130 ugh = ttodata(src+2, 0, 16, (char *)id->name.ptr
131 , strlen(src), &id->name.len);
132 }
133- - else if (*(src+1) == '[')
134+ else if (!oe_only && *(src+1) == '[')
135 {
136 /* if there is a second specifier ([) on the line
137 * we interprete this as a text ID_KEY_ID, and we remove
138diff --git a/lib/libswan/secrets.c b/lib/libswan/secrets.c
139index 6e9466b..8ff80e0 100644
140- --- a/lib/libswan/secrets.c
141+++ b/lib/libswan/secrets.c
142@@ -1223,7 +1223,7 @@ lsw_process_secret_records(struct secret **psecrets, int verbose,
143 }
144 else
145 {
146- - ugh = atoid(flp->tok, &id, FALSE);
147+ ugh = atoid(flp->tok, &id, FALSE, FALSE);
148 }
149
150 if (ugh != NULL)
151diff --git a/lib/libswan/x509dn.c b/lib/libswan/x509dn.c
152index 61407e5..7731856 100644
153- --- a/lib/libswan/x509dn.c
154+++ b/lib/libswan/x509dn.c
155@@ -472,7 +472,7 @@ static const x501rdn_t x501rdns[] = {
156 {"TCGID" , {oid_TCGID, 12}, ASN1_PRINTABLESTRING}
157 };
158
159- -#define X501_RDN_ROOF 24
160+#define X501_RDN_ROOF elemsof(x501rdns)
161
162 /* Maximum length of ASN.1 distinquished name */
163 #define ASN1_BUF_LEN 512
164@@ -775,11 +775,11 @@ atodn(char *src, chunk_t *dn)
165 UNKNOWN_OID = 4
166 } state_t;
167
168- - u_char oid_len_buf[3];
169- - u_char name_len_buf[3];
170- - u_char rdn_seq_len_buf[3];
171- - u_char rdn_set_len_buf[3];
172- - u_char dn_seq_len_buf[3];
173+ u_char oid_len_buf[ASN1_MAX_LEN_LEN];
174+ u_char name_len_buf[ASN1_MAX_LEN_LEN];
175+ u_char rdn_seq_len_buf[ASN1_MAX_LEN_LEN];
176+ u_char rdn_set_len_buf[ASN1_MAX_LEN_LEN];
177+ u_char dn_seq_len_buf[ASN1_MAX_LEN_LEN];
178
179 chunk_t asn1_oid_len = { oid_len_buf, 0 };
180 chunk_t asn1_name_len = { name_len_buf, 0 };
181@@ -797,7 +797,7 @@ atodn(char *src, chunk_t *dn)
182
183 err_t ugh = NULL;
184
185- - u_char *dn_ptr = dn->ptr + 4;
186+ u_char *dn_ptr = dn->ptr + 1 + ASN1_MAX_LEN_LEN; /* leave room for prefix */
187
188 state_t state = SEARCH_OID;
189
190@@ -885,25 +885,37 @@ atodn(char *src, chunk_t *dn)
191 code_asn1_length(rdn_set_len, &asn1_rdn_set_len);
192
193 /* encode the relative distinguished name */
194- - *dn_ptr++ = ASN1_SET;
195- - chunkcpy(dn_ptr, asn1_rdn_set_len);
196- - *dn_ptr++ = ASN1_SEQUENCE;
197- - chunkcpy(dn_ptr, asn1_rdn_seq_len);
198- - *dn_ptr++ = ASN1_OID;
199- - chunkcpy(dn_ptr, asn1_oid_len);
200- - chunkcpy(dn_ptr, x501rdns[pos].oid);
201- - /* encode the ASN.1 character string type of the name */
202- - *dn_ptr++ = (x501rdns[pos].type == ASN1_PRINTABLESTRING
203- - && !is_printablestring(name))? ASN1_T61STRING : x501rdns[pos].type;
204- - chunkcpy(dn_ptr, asn1_name_len);
205- - chunkcpy(dn_ptr, name);
206- -
207- - /* accumulate the length of the distinguished name sequence */
208- - dn_seq_len += 1 + asn1_rdn_set_len.len + rdn_set_len;
209- -
210- - /* reset name and change state */
211- - name = empty_chunk;
212- - state = SEARCH_OID;
213+ if (IDTOA_BUF < dn_ptr - dn->ptr
214+ + 1 + asn1_rdn_set_len.len /* set */
215+ + 1 + asn1_rdn_seq_len.len /* sequence */
216+ + 1 + asn1_oid_len.len + x501rdns[pos].oid.len /* oid len, oid */
217+ + 1 + asn1_name_len.len + name.len /* type name */
218+ ) {
219+ /* no room! */
220+ ugh = "DN is too big";
221+ state = UNKNOWN_OID;
222+ /* I think that it is safe to continue (but perhaps pointless) */
223+ } else {
224+ *dn_ptr++ = ASN1_SET;
225+ chunkcpy(dn_ptr, asn1_rdn_set_len);
226+ *dn_ptr++ = ASN1_SEQUENCE;
227+ chunkcpy(dn_ptr, asn1_rdn_seq_len);
228+ *dn_ptr++ = ASN1_OID;
229+ chunkcpy(dn_ptr, asn1_oid_len);
230+ chunkcpy(dn_ptr, x501rdns[pos].oid);
231+ /* encode the ASN.1 character string type of the name */
232+ *dn_ptr++ = (x501rdns[pos].type == ASN1_PRINTABLESTRING
233+ && !is_printablestring(name))? ASN1_T61STRING : x501rdns[pos].type;
234+ chunkcpy(dn_ptr, asn1_name_len);
235+ chunkcpy(dn_ptr, name);
236+
237+ /* accumulate the length of the distinguished name sequence */
238+ dn_seq_len += 1 + asn1_rdn_set_len.len + rdn_set_len;
239+
240+ /* reset name and change state */
241+ name = empty_chunk;
242+ state = SEARCH_OID;
243+ }
244 }
245 break;
246 case UNKNOWN_OID:
247@@ -911,9 +923,9 @@ atodn(char *src, chunk_t *dn)
248 }
249 } while (*src++ != '\0');
250
251- - /* complete the distinguished name sequence*/
252- - code_asn1_length(dn_seq_len, &asn1_dn_seq_len);
253- - dn->ptr += 3 - asn1_dn_seq_len.len;
254+ /* complete the distinguished name sequence: prefix it with ASN1_SEQUENCE and length */
255+ code_asn1_length((size_t)dn_seq_len, &asn1_dn_seq_len);
256+ dn->ptr += ASN1_MAX_LEN_LEN + 1 - 1 - asn1_dn_seq_len.len;
257 dn->len = 1 + asn1_dn_seq_len.len + dn_seq_len;
258 dn_ptr = dn->ptr;
259 *dn_ptr++ = ASN1_SEQUENCE;
260diff --git a/programs/pluto/connections.c b/programs/pluto/connections.c
261index e8d326b..f08521b 100644
262- --- a/programs/pluto/connections.c
263+++ b/programs/pluto/connections.c
264@@ -911,7 +911,7 @@ extract_end(struct end *dst, const struct whack_end *src, const char *which)
265 }
266 else
267 {
268- - err_t ugh = atoid(src->id, &dst->id, TRUE);
269+ err_t ugh = atoid(src->id, &dst->id, TRUE, FALSE);
270
271 if (ugh != NULL)
272 {
273diff --git a/programs/pluto/dnskey.c b/programs/pluto/dnskey.c
274index 5525d12..78f1d0a 100644
275- --- a/programs/pluto/dnskey.c
276+++ b/programs/pluto/dnskey.c
277@@ -277,8 +277,12 @@ decode_iii(char **pp, struct id *gw_id)
278 if (*p == '@')
279 {
280 /* gateway specification in this record is @FQDN */
281- - err_t ugh = atoid(p, gw_id, FALSE);
282
283+ if(strspn(p,' ') >= IDTOA_BUF) {
284+ return builddiag("malformed FQDN in TXT " our_TXT_attr_string ": ID too large for IDTOA_BUF");
285+ }
286+
287+ err_t ugh = atoid(p, gw_id, FALSE, TRUE); /* only run OE related parts of atoid() */
288 if (ugh != NULL)
289 return builddiag("malformed FQDN in TXT " our_TXT_attr_string ": %s"
290 , ugh);
291diff --git a/programs/pluto/myid.c b/programs/pluto/myid.c
292index bdd0e12..2e92f25 100644
293- --- a/programs/pluto/myid.c
294+++ b/programs/pluto/myid.c
295@@ -103,7 +103,7 @@ set_myid(enum myid_state s, char *idstr)
296 if (idstr != NULL)
297 {
298 struct id id;
299- - err_t ugh = atoid(idstr, &id, FALSE);
300+ err_t ugh = atoid(idstr, &id, FALSE, FALSE);
301
302 if (ugh != NULL)
303 {
304diff --git a/programs/pluto/rcv_whack.c b/programs/pluto/rcv_whack.c
305index 1725357..7d5072c 100644
306- --- a/programs/pluto/rcv_whack.c
307+++ b/programs/pluto/rcv_whack.c
308@@ -259,7 +259,7 @@ static void
309 key_add_request(const struct whack_message *msg)
310 {
311 struct id keyid;
312- - err_t ugh = atoid(msg->keyid, &keyid, FALSE);
313+ err_t ugh = atoid(msg->keyid, &keyid, FALSE, FALSE);
314
315 if (ugh != NULL)
316 {
317diff --git a/programs/showhostkey/showhostkey.c b/programs/showhostkey/showhostkey.c
318index c9fe9cf..bf87080 100644
319- --- a/programs/showhostkey/showhostkey.c
320+++ b/programs/showhostkey/showhostkey.c
321@@ -203,7 +203,7 @@ struct secret *pick_key(struct secret *host_secrets
322 struct secret *s;
323 err_t e;
324
325- - e = atoid(idname, &id, FALSE);
326+ e = atoid(idname, &id, FALSE, FALSE);
327 if(e) {
328 printf("%s: key '%s' is invalid\n", progname, idname);
329 exit(4);
330-----BEGIN PGP SIGNATURE-----
331Version: GnuPG v1.4.13 (GNU/Linux)
332
333iQIcBAEBCAAGBQJRkWmnAAoJEIX/S0OzD8b5EZIP+wb5LyvL4jXGYJzvalkCjWL3
3341cZp5H672jGdVvW/G3bJ5unhjpRt9ASxebHR/4LfWZuWG5U4gdPRjcz1YcuNwVnB
335xOXZ4ELWYRFFblkkHz+GO5rSRwmWhFnyGvDdN5Oh6VBcmegHvaKk6uVLPXZJpVdg
3362U1+s+x3EkrcP6IJyTa9pyhZiDWcdYVn3seyHcFCNa3R/Xkwefi3HwA2w8+L18NX
337NvIMUx2aXj70cBE5VAg+XJWIZ2Rrlf2zHDM96GUUfGIIH1mzpuxYCFbpGqISmOYI
338AAumQ9I4kQGy0ZkWn41Et3ppJvcRFoMlAz70Ay+nbZ/+eqQH9B3KfplfX2UrsXAn
339SVvMPypkMfjhUbPG8AWr//6+a0uZxa0PyibNXhhdr+3ocANaZ8ty+ehFmVl0DIBM
340rc582erQ8s4Bj8v+4vy1TzkR5HXWhwWhCjD0EnU8zGGjZ2u+1BAYgzTUG4Nqo+/Q
341ziJdc71vy+OqyLXTFMdekUuRl40BXuFHHUv6jWeslgIh2/1Z/A0NZzxs2sMFCkEW
342anTG32ridJSCqQhSXZ4xW07O5F45csH6qgze2jQdYEizATYsDqeKazEZhmakUsow
343v5gj85f5VYGWjoYjKr/HbrueEbeGpV3Twf4tZ6XyCxAjJEt6N8XWidSiMeL3gNIm
344cgXmYH+ak4nDLJGyaYDt
345=5y9o
346-----END PGP SIGNATURE-----
diff --git a/main/openswan/openswan-libreswan-backport-949437-atodn.patch b/main/openswan/openswan-libreswan-backport-949437-atodn.patch
new file mode 100644
index 0000000000..524a75b20f
--- /dev/null
+++ b/main/openswan/openswan-libreswan-backport-949437-atodn.patch
@@ -0,0 +1,278 @@
1diff -Naur openswan-2.6.32-orig/include/asn1.h openswan-2.6.32/include/asn1.h
2--- openswan-2.6.32-orig/include/asn1.h 2010-12-17 20:23:54.000000000 -0500
3+++ openswan-2.6.32/include/asn1.h 2013-04-24 13:11:05.799140126 -0400
4@@ -84,8 +84,10 @@
5 #define ASN1_BODY 0x20
6 #define ASN1_RAW 0x40
7
8-#define ASN1_INVALID_LENGTH 0xffffffff
9+#define ASN1_INVALID_LENGTH (~(size_t) 0) /* largest size_t */
10
11+#define ASN1_MAX_LEN (1U << (8*3)) /* don't handle objects with length greater than this */
12+#define ASN1_MAX_LEN_LEN 4 /* no coded length takes more than 4 bytes. */
13
14 /* definition of an ASN.1 object */
15
16diff -Naur openswan-2.6.32-orig/include/id.h openswan-2.6.32/include/id.h
17--- openswan-2.6.32-orig/include/id.h 2010-12-17 20:23:54.000000000 -0500
18+++ openswan-2.6.32/include/id.h 2013-04-24 13:11:05.799140126 -0400
19@@ -46,7 +46,7 @@
20 extern const struct id *resolve_myid(const struct id *id);
21 extern void set_myFQDN(void);
22
23-extern err_t atoid(char *src, struct id *id, bool myid_ok);
24+extern err_t atoid(char *src, struct id *id, bool myid_ok, bool oe_only);
25 extern void iptoid(const ip_address *ip, struct id *id);
26 extern unsigned char* temporary_cyclic_buffer(void);
27 extern int idtoa(const struct id *id, char *dst, size_t dstlen);
28diff -Naur openswan-2.6.32-orig/lib/libopenswan/id.c openswan-2.6.32/lib/libopenswan/id.c
29--- openswan-2.6.32-orig/lib/libopenswan/id.c 2010-12-17 20:23:54.000000000 -0500
30+++ openswan-2.6.32/lib/libopenswan/id.c 2013-04-24 13:11:05.799140126 -0400
31@@ -57,27 +57,29 @@
32
33 /* Convert textual form of id into a (temporary) struct id.
34 * Note that if the id is to be kept, unshare_id_content will be necessary.
35+ * This function should be split into parts so the boolean arguments can be
36+ * removed -- Paul
37 */
38 err_t
39-atoid(char *src, struct id *id, bool myid_ok)
40+atoid(char *src, struct id *id, bool myid_ok, bool oe_only)
41 {
42 err_t ugh = NULL;
43
44 *id = empty_id;
45
46- if (myid_ok && streq("%myid", src))
47+ if (!oe_only && myid_ok && streq("%myid", src))
48 {
49 id->kind = ID_MYID;
50 }
51- else if (streq("%fromcert", src))
52+ else if (!oe_only && streq("%fromcert", src))
53 {
54 id->kind = ID_FROMCERT;
55 }
56- else if (streq("%none", src))
57+ else if (!oe_only && streq("%none", src))
58 {
59 id->kind = ID_NONE;
60 }
61- else if (strchr(src, '=') != NULL)
62+ else if (!oe_only && strchr(src, '=') != NULL)
63 {
64 /* we interpret this as an ASCII X.501 ID_DER_ASN1_DN */
65 id->kind = ID_DER_ASN1_DN;
66@@ -111,7 +113,7 @@
67 {
68 if (*src == '@')
69 {
70- if (*(src+1) == '#')
71+ if (!oe_only && *(src+1) == '#')
72 {
73 /* if there is a second specifier (#) on the line
74 * we interprete this as ID_KEY_ID
75@@ -122,7 +124,7 @@
76 ugh = ttodata(src+2, 0, 16, (char *)id->name.ptr
77 , strlen(src), &id->name.len);
78 }
79- else if (*(src+1) == '~')
80+ else if (!oe_only && *(src+1) == '~')
81 {
82 /* if there is a second specifier (~) on the line
83 * we interprete this as a binary ID_DER_ASN1_DN
84@@ -133,7 +135,7 @@
85 ugh = ttodata(src+2, 0, 16, (char *)id->name.ptr
86 , strlen(src), &id->name.len);
87 }
88- else if (*(src+1) == '[')
89+ else if (!oe_only && *(src+1) == '[')
90 {
91 /* if there is a second specifier ([) on the line
92 * we interprete this as a text ID_KEY_ID, and we remove
93diff -Naur openswan-2.6.32-orig/lib/libopenswan/secrets.c openswan-2.6.32/lib/libopenswan/secrets.c
94--- openswan-2.6.32-orig/lib/libopenswan/secrets.c 2010-12-17 20:23:54.000000000 -0500
95+++ openswan-2.6.32/lib/libopenswan/secrets.c 2013-04-24 13:11:05.800140140 -0400
96@@ -1299,7 +1299,7 @@
97 }
98 else
99 {
100- ugh = atoid(flp->tok, &id, FALSE);
101+ ugh = atoid(flp->tok, &id, FALSE, FALSE);
102 }
103
104 if (ugh != NULL)
105diff -Naur openswan-2.6.32-orig/lib/libopenswan/x509dn.c openswan-2.6.32/lib/libopenswan/x509dn.c
106--- openswan-2.6.32-orig/lib/libopenswan/x509dn.c 2010-12-17 20:23:54.000000000 -0500
107+++ openswan-2.6.32/lib/libopenswan/x509dn.c 2013-04-24 13:11:05.801140153 -0400
108@@ -476,7 +476,7 @@
109 {"TCGID" , {oid_TCGID, 12}, ASN1_PRINTABLESTRING}
110 };
111
112-#define X501_RDN_ROOF 24
113+#define X501_RDN_ROOF elemsof(x501rdns)
114
115 /* Maximum length of ASN.1 distinquished name */
116 #define ASN1_BUF_LEN 512
117@@ -746,11 +746,11 @@
118 UNKNOWN_OID = 4
119 } state_t;
120
121- u_char oid_len_buf[3];
122- u_char name_len_buf[3];
123- u_char rdn_seq_len_buf[3];
124- u_char rdn_set_len_buf[3];
125- u_char dn_seq_len_buf[3];
126+ u_char oid_len_buf[ASN1_MAX_LEN_LEN];
127+ u_char name_len_buf[ASN1_MAX_LEN_LEN];
128+ u_char rdn_seq_len_buf[ASN1_MAX_LEN_LEN];
129+ u_char rdn_set_len_buf[ASN1_MAX_LEN_LEN];
130+ u_char dn_seq_len_buf[ASN1_MAX_LEN_LEN];
131
132 chunk_t asn1_oid_len = { oid_len_buf, 0 };
133 chunk_t asn1_name_len = { name_len_buf, 0 };
134@@ -768,7 +768,7 @@
135
136 err_t ugh = NULL;
137
138- u_char *dn_ptr = dn->ptr + 4;
139+ u_char *dn_ptr = dn->ptr + 1 + ASN1_MAX_LEN_LEN; /* leave room for prefix */
140
141 state_t state = SEARCH_OID;
142
143@@ -841,25 +841,37 @@
144 code_asn1_length(rdn_set_len, &asn1_rdn_set_len);
145
146 /* encode the relative distinguished name */
147- *dn_ptr++ = ASN1_SET;
148- chunkcpy(dn_ptr, asn1_rdn_set_len);
149- *dn_ptr++ = ASN1_SEQUENCE;
150- chunkcpy(dn_ptr, asn1_rdn_seq_len);
151- *dn_ptr++ = ASN1_OID;
152- chunkcpy(dn_ptr, asn1_oid_len);
153- chunkcpy(dn_ptr, x501rdns[pos].oid);
154- /* encode the ASN.1 character string type of the name */
155- *dn_ptr++ = (x501rdns[pos].type == ASN1_PRINTABLESTRING
156- && !is_printablestring(name))? ASN1_T61STRING : x501rdns[pos].type;
157- chunkcpy(dn_ptr, asn1_name_len);
158- chunkcpy(dn_ptr, name);
159-
160- /* accumulate the length of the distinguished name sequence */
161- dn_seq_len += 1 + asn1_rdn_set_len.len + rdn_set_len;
162-
163- /* reset name and change state */
164- name = empty_chunk;
165- state = SEARCH_OID;
166+ if (IDTOA_BUF < dn_ptr - dn->ptr
167+ + 1 + asn1_rdn_set_len.len /* set */
168+ + 1 + asn1_rdn_seq_len.len /* sequence */
169+ + 1 + asn1_oid_len.len + x501rdns[pos].oid.len /* oid len, oid */
170+ + 1 + asn1_name_len.len + name.len /* type name */
171+ ) {
172+ /* no room! */
173+ ugh = "DN is too big";
174+ state = UNKNOWN_OID;
175+ /* I think that it is safe to continue (but perhaps pointless) */
176+ } else {
177+ *dn_ptr++ = ASN1_SET;
178+ chunkcpy(dn_ptr, asn1_rdn_set_len);
179+ *dn_ptr++ = ASN1_SEQUENCE;
180+ chunkcpy(dn_ptr, asn1_rdn_seq_len);
181+ *dn_ptr++ = ASN1_OID;
182+ chunkcpy(dn_ptr, asn1_oid_len);
183+ chunkcpy(dn_ptr, x501rdns[pos].oid);
184+ /* encode the ASN.1 character string type of the name */
185+ *dn_ptr++ = (x501rdns[pos].type == ASN1_PRINTABLESTRING
186+ && !is_printablestring(name))? ASN1_T61STRING : x501rdns[pos].type;
187+ chunkcpy(dn_ptr, asn1_name_len);
188+ chunkcpy(dn_ptr, name);
189+
190+ /* accumulate the length of the distinguished name sequence */
191+ dn_seq_len += 1 + asn1_rdn_set_len.len + rdn_set_len;
192+
193+ /* reset name and change state */
194+ name = empty_chunk;
195+ state = SEARCH_OID;
196+ }
197 }
198 break;
199 case UNKNOWN_OID:
200@@ -867,9 +879,10 @@
201 }
202 } while (*src++ != '\0');
203
204- /* complete the distinguished name sequence*/
205- code_asn1_length(dn_seq_len, &asn1_dn_seq_len);
206- dn->ptr += 3 - asn1_dn_seq_len.len;
207+ /* complete the distinguished name sequence: prefix it with ASN1_SEQUENCE and length */
208+
209+ code_asn1_length((size_t)dn_seq_len, &asn1_dn_seq_len);
210+ dn->ptr += ASN1_MAX_LEN_LEN + 1 - 1 - asn1_dn_seq_len.len;
211 dn->len = 1 + asn1_dn_seq_len.len + dn_seq_len;
212 dn_ptr = dn->ptr;
213 *dn_ptr++ = ASN1_SEQUENCE;
214diff -Naur openswan-2.6.32-orig/programs/pluto/connections.c openswan-2.6.32/programs/pluto/connections.c
215--- openswan-2.6.32-orig/programs/pluto/connections.c 2013-04-24 13:10:30.520656796 -0400
216+++ openswan-2.6.32/programs/pluto/connections.c 2013-04-24 13:11:05.802140167 -0400
217@@ -891,7 +891,7 @@
218 }
219 else
220 {
221- err_t ugh = atoid(src->id, &dst->id, TRUE);
222+ err_t ugh = atoid(src->id, &dst->id, TRUE, FALSE);
223
224 if (ugh != NULL)
225 {
226diff -Naur openswan-2.6.32-orig/programs/pluto/dnskey.c openswan-2.6.32/programs/pluto/dnskey.c
227--- openswan-2.6.32-orig/programs/pluto/dnskey.c 2010-12-17 20:23:54.000000000 -0500
228+++ openswan-2.6.32/programs/pluto/dnskey.c 2013-04-24 13:11:05.803140181 -0400
229@@ -289,8 +289,12 @@
230 if (*p == '@')
231 {
232 /* gateway specification in this record is @FQDN */
233- err_t ugh = atoid(p, gw_id, FALSE);
234
235+ if(strspn(p," ") >= IDTOA_BUF) {
236+ return builddiag("malformed FQDN in TXT " our_TXT_attr_string ": ID too large for IDTOA_BUF");
237+ }
238+
239+ err_t ugh = atoid(p, gw_id, FALSE, TRUE); /* only run OE related parts of atoid() */
240 if (ugh != NULL)
241 return builddiag("malformed FQDN in TXT " our_TXT_attr_string ": %s"
242 , ugh);
243diff -Naur openswan-2.6.32-orig/programs/pluto/myid.c openswan-2.6.32/programs/pluto/myid.c
244--- openswan-2.6.32-orig/programs/pluto/myid.c 2010-12-17 20:23:54.000000000 -0500
245+++ openswan-2.6.32/programs/pluto/myid.c 2013-04-24 13:11:05.803140181 -0400
246@@ -103,7 +103,7 @@
247 if (idstr != NULL)
248 {
249 struct id id;
250- err_t ugh = atoid(idstr, &id, FALSE);
251+ err_t ugh = atoid(idstr, &id, FALSE, FALSE);
252
253 if (ugh != NULL)
254 {
255diff -Naur openswan-2.6.32-orig/programs/pluto/rcv_whack.c openswan-2.6.32/programs/pluto/rcv_whack.c
256--- openswan-2.6.32-orig/programs/pluto/rcv_whack.c 2013-04-24 13:10:30.392655041 -0400
257+++ openswan-2.6.32/programs/pluto/rcv_whack.c 2013-04-24 13:11:05.803140181 -0400
258@@ -243,7 +243,7 @@
259 key_add_request(const struct whack_message *msg)
260 {
261 struct id keyid;
262- err_t ugh = atoid(msg->keyid, &keyid, FALSE);
263+ err_t ugh = atoid(msg->keyid, &keyid, FALSE, FALSE);
264
265 if (ugh != NULL)
266 {
267diff -Naur openswan-2.6.32-orig/programs/showhostkey/showhostkey.c openswan-2.6.32/programs/showhostkey/showhostkey.c
268--- openswan-2.6.32-orig/programs/showhostkey/showhostkey.c 2010-12-17 20:23:54.000000000 -0500
269+++ openswan-2.6.32/programs/showhostkey/showhostkey.c 2013-04-24 13:11:05.804140194 -0400
270@@ -208,7 +208,7 @@
271 struct secret *s;
272 err_t e;
273
274- e = atoid(idname, &id, FALSE);
275+ e = atoid(idname, &id, FALSE, FALSE);
276 if(e) {
277 printf("%s: key '%s' is invalid\n", progname, idname);
278 exit(4);
diff --git a/main/openswan/openswan-libreswan-backport-949437-do_3des.patch b/main/openswan/openswan-libreswan-backport-949437-do_3des.patch
new file mode 100644
index 0000000000..75dbe3b636
--- /dev/null
+++ b/main/openswan/openswan-libreswan-backport-949437-do_3des.patch
@@ -0,0 +1,61 @@
1From acdd65497d164082e0462b3f2d4407f0c50ccf71 Mon Sep 17 00:00:00 2001
2From: Florian Weimer <fweimer@redhat.com>
3Date: Wed, 10 Apr 2013 10:32:52 +0200
4Subject: [PATCH 06/10] do_3des: Abort on failure
5
6The routine cannot signal encryption failures to the caller
7and would leave the buffer unencrypted on error.
8---
9 lib/libopenswan/pem.c | 14 ++++++++++----
10 1 file changed, 10 insertions(+), 4 deletions(-)
11
12diff --git a/lib/libopenswan/pem.c b/lib/libopenswan/pem.c
13index 36da401..d42655a 100644
14--- a/lib/libopenswan/pem.c
15+++ b/lib/libopenswan/pem.c
16@@ -483,7 +483,7 @@ void do_3des_nss(u_int8_t *buf, size_t buf_len
17 memcpy(&symkey, key, key_size);
18 if (symkey == NULL) {
19 loglog(RC_LOG_SERIOUS, "do_3des: NSS derived enc key is NULL \n");
20- goto out;
21+ abort();
22 }
23
24 ivitem.type = siBuffer;
25@@ -493,7 +493,7 @@ void do_3des_nss(u_int8_t *buf, size_t buf_len
26 secparam = PK11_ParamFromIV(ciphermech, &ivitem);
27 if (secparam == NULL) {
28 loglog(RC_LOG_SERIOUS, "do_3des: Failure to set up PKCS11 param (err %d)\n",PR_GetError());
29- goto out;
30+ abort();
31 }
32
33 outlen = 0;
34@@ -505,8 +505,15 @@ void do_3des_nss(u_int8_t *buf, size_t buf_len
35 }
36
37 enccontext = PK11_CreateContextBySymKey(ciphermech, enc? CKA_ENCRYPT: CKA_DECRYPT, symkey, secparam);
38+ if (enccontext == NULL) {
39+ loglog(RC_LOG_SERIOUS, "do_3des: PKCS11 context creation failure (err %d)\n", PR_GetError());
40+ abort();
41+ }
42 rv = PK11_CipherOp(enccontext, tmp_buf, &outlen, buf_len, buf, buf_len);
43- passert(rv==SECSuccess);
44+ if (rv != SECSuccess) {
45+ loglog(RC_LOG_SERIOUS, "do_3des: PKCS11 operation failure (err %d)\n", PR_GetError());
46+ abort();
47+ }
48
49 if(enc) {
50 memcpy(new_iv, (char*) tmp_buf + buf_len-DES_CBC_BLOCK_SIZE, DES_CBC_BLOCK_SIZE);
51@@ -518,7 +525,6 @@ void do_3des_nss(u_int8_t *buf, size_t buf_len
52 PR_Free(tmp_buf);
53 PR_Free(new_iv);
54
55-out:
56 if (secparam) {
57 SECITEM_FreeItem(secparam, PR_TRUE);
58 }
59--
601.8.1.4
61
diff --git a/main/openswan/openswan-libreswan-backport-949437-do_aes.patch b/main/openswan/openswan-libreswan-backport-949437-do_aes.patch
new file mode 100644
index 0000000000..aedb4d34ab
--- /dev/null
+++ b/main/openswan/openswan-libreswan-backport-949437-do_aes.patch
@@ -0,0 +1,62 @@
1From ee267f812f6d72da400cc24265c399c3e9048a8a Mon Sep 17 00:00:00 2001
2From: Florian Weimer <fweimer@redhat.com>
3Date: Wed, 10 Apr 2013 10:33:02 +0200
4Subject: [PATCH 07/10] do_aes: Abort on failure
5
6The routine cannot signal encryption failures to the caller
7and would leave the buffer unencrypted on error.
8---
9 programs/pluto/ike_alg_aes.c | 15 ++++++++++-----
10 1 file changed, 10 insertions(+), 5 deletions(-)
11
12diff --git a/programs/pluto/ike_alg_aes.c b/programs/pluto/ike_alg_aes.c
13index 1d4aada..95999bb 100644
14--- a/programs/pluto/ike_alg_aes.c
15+++ b/programs/pluto/ike_alg_aes.c
16@@ -48,7 +48,7 @@ do_aes(u_int8_t *buf, size_t buf_len, u_int8_t *key, size_t key_size, u_int8_t *
17
18 if (symkey == NULL) {
19 loglog(RC_LOG_SERIOUS, "do_aes: NSS derived enc key in NULL\n");
20- goto out;
21+ abort();
22 }
23
24 ivitem.type = siBuffer;
25@@ -58,7 +58,7 @@ do_aes(u_int8_t *buf, size_t buf_len, u_int8_t *key, size_t key_size, u_int8_t *
26 secparam = PK11_ParamFromIV(ciphermech, &ivitem);
27 if (secparam == NULL) {
28 loglog(RC_LOG_SERIOUS, "do_aes: Failure to set up PKCS11 param (err %d)\n",PR_GetError());
29- goto out;
30+ abort();
31 }
32
33 outlen = 0;
34@@ -69,8 +69,15 @@ do_aes(u_int8_t *buf, size_t buf_len, u_int8_t *key, size_t key_size, u_int8_t *
35 }
36
37 enccontext = PK11_CreateContextBySymKey(ciphermech, enc? CKA_ENCRYPT : CKA_DECRYPT, symkey, secparam);
38+ if (enccontext == NULL) {
39+ loglog(RC_LOG_SERIOUS, "do_aes: PKCS11 context creation failure (err %d)\n", PR_GetError());
40+ abort();
41+ }
42 rv = PK11_CipherOp(enccontext, tmp_buf, &outlen, buf_len, buf, buf_len);
43- passert(rv==SECSuccess);
44+ if (rv != SECSuccess) {
45+ loglog(RC_LOG_SERIOUS, "do_aes: PKCS11 operation failure (err %d)\n", PR_GetError());
46+ abort();
47+ }
48 PK11_DestroyContext(enccontext, PR_TRUE);
49 memcpy(buf,tmp_buf,buf_len);
50
51@@ -81,8 +88,6 @@ do_aes(u_int8_t *buf, size_t buf_len, u_int8_t *key, size_t key_size, u_int8_t *
52 memcpy(iv, new_iv, AES_CBC_BLOCK_SIZE);
53 PR_Free(tmp_buf);
54
55-out:
56-
57 if (secparam)
58 SECITEM_FreeItem(secparam, PR_TRUE);
59 DBG(DBG_CRYPT, DBG_log("NSS do_aes: exit"));
60--
611.8.1.4
62
diff --git a/main/openswan/openswan-libreswan-backport-949437-x509dn.patch b/main/openswan/openswan-libreswan-backport-949437-x509dn.patch
new file mode 100644
index 0000000000..2d41293771
--- /dev/null
+++ b/main/openswan/openswan-libreswan-backport-949437-x509dn.patch
@@ -0,0 +1,79 @@
1diff --git a/lib/libopenswan/x509dn.c b/lib/libopenswan/x509dn.c
2index 7731856..43c4bb5 100644
3--- a/lib/libopenswan/x509dn.c
4+++ b/lib/libopenswan/x509dn.c
5@@ -477,11 +477,25 @@ static const x501rdn_t x501rdns[] = {
6 /* Maximum length of ASN.1 distinquished name */
7 #define ASN1_BUF_LEN 512
8
9+static void format_chunk(chunk_t *ch, const char *format, ...) PRINTF_LIKE(2);
10+
11 static void
12-update_chunk(chunk_t *ch, int n)
13+format_chunk(chunk_t *ch, const char *format, ...)
14 {
15- n = (n > -1 && n < (int)ch->len)? n : (int)ch->len-1;
16- ch->ptr += n; ch->len -= n;
17+ if (ch->len > 0) {
18+ size_t len = ch->len;
19+ va_list args;
20+ va_start(args, format);
21+ int ret = vsnprintf((char *)ch->ptr, len, format, args);
22+ va_end(args);
23+ if (ret < 0 || ret > len) {
24+ ch->ptr += len;
25+ ch->len = 0;
26+ } else {
27+ ch->ptr += ret;
28+ ch->len -= ret;
29+ }
30+ }
31 }
32
33
34@@ -612,9 +626,7 @@ dn_parse(chunk_t dn, chunk_t *str)
35 err_t ugh;
36
37 if(dn.ptr == NULL) {
38- const char *e = "(empty)";
39- strncpy((char *)str->ptr, e, str->len);
40- update_chunk(str, strlen(e));
41+ format_chunk(str, "(empty)");
42 return NULL;
43 }
44 ugh = init_rdn(dn, &rdn, &attribute, &next);
45@@ -632,19 +644,17 @@ dn_parse(chunk_t dn, chunk_t *str)
46 if (first) /* first OID/value pair */
47 first = FALSE;
48 else /* separate OID/value pair by a comma */
49- update_chunk(str, snprintf((char *)str->ptr,str->len,", "));
50+ format_chunk(str, ", ");
51
52 /* print OID */
53 oid_code = known_oid(oid);
54 if (oid_code == OID_UNKNOWN) /* OID not found in list */
55 hex_str(oid, str);
56 else
57- update_chunk(str, snprintf((char *)str->ptr,str->len,"%s",
58- oid_names[oid_code].name));
59+ format_chunk(str, "%s", oid_names[oid_code].name);
60
61 /* print value */
62- update_chunk(str, snprintf((char *)str->ptr,str->len,"=%.*s",
63- (int)value.len,value.ptr));
64+ format_chunk(str, "=%.*s", (int)value.len, value.ptr);
65 }
66 return NULL;
67 }
68@@ -684,9 +694,9 @@ void
69 hex_str(chunk_t bin, chunk_t *str)
70 {
71 u_int i;
72- update_chunk(str, snprintf((char *)str->ptr,str->len,"0x"));
73+ format_chunk(str, "0x");
74 for (i=0; i < bin.len; i++)
75- update_chunk(str, snprintf((char *)str->ptr,str->len,"%02X",*bin.ptr++));
76+ format_chunk(str, "%02X", *bin.ptr++);
77 }
78
79