aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTimo Teräs <timo.teras@iki.fi>2014-04-17 07:01:16 +0000
committerNatanael Copa <ncopa@alpinelinux.org>2014-04-18 13:04:02 +0000
commit1df893d29e73824172978ca87bc5575b1fcace34 (patch)
tree7b543306c16f306e2560d21c9029c34ebfa1fc2e
parentb40a99c8c0a04a119db0f5fad7fbe186981f054c (diff)
downloadaports-1df893d29e73824172978ca87bc5575b1fcace34.tar.bz2
aports-1df893d29e73824172978ca87bc5575b1fcace34.tar.xz
main/openswan: security upgrade to 2.6.41 (CVE-2013-6466)
fixes #2827
-rw-r--r--main/openswan/APKBUILD46
-rw-r--r--main/openswan/CVE-2013-2052.patch346
-rw-r--r--main/openswan/fix-natt.patch39
-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
7 files changed, 57 insertions, 854 deletions
diff --git a/main/openswan/APKBUILD b/main/openswan/APKBUILD
index f126798a8a..d261c89c00 100644
--- a/main/openswan/APKBUILD
+++ b/main/openswan/APKBUILD
@@ -1,8 +1,8 @@
# Contributor: Danilo Godec <danilo.godec@agenda.si>
# Maintainer: Borys Zhukov <mp5@mp5.im>
pkgname=openswan
-pkgver=2.6.38
-pkgrel=2
+pkgver=2.6.41
+pkgrel=0
pkgdesc="IPsec Implementation which Allows Building of VPNs"
url="http://www.openswan.org/"
arch="all"
@@ -12,11 +12,10 @@ makedepends="gmp-dev bison flex coreutils bash"
install=""
subpackages="$pkgname-doc"
source="http://download.openswan.org/openswan/$pkgname-$pkgver.tar.gz
- openswan-libreswan-backport-949437-atodn.patch
- openswan-libreswan-backport-949437-do_3des.patch
- openswan-libreswan-backport-949437-do_aes.patch
- openswan-libreswan-backport-949437-x509dn.patch
- ipsec.initd setup.patch"
+ fix-natt.patch
+ setup.patch
+ ipsec.initd
+ "
_builddir="$srcdir"/$pkgname-$pkgver
prepare() {
@@ -54,24 +53,15 @@ package() {
cp -aR docs/* "$pkgdir"/usr/share/doc/$pkgname/
}
-md5sums="13073eb5314b83a31be88e4117e8bbcd openswan-2.6.38.tar.gz
-500e936c90ad27545d0ab6450fd888aa openswan-libreswan-backport-949437-atodn.patch
-6dcfd099ed2cf90231c36ba305e46348 openswan-libreswan-backport-949437-do_3des.patch
-578f171370c373e3501b85de7efc3045 openswan-libreswan-backport-949437-do_aes.patch
-730a94960fe593f12b8d1f4ff9266d2a openswan-libreswan-backport-949437-x509dn.patch
-f019d1fa23627d54462054fedc9de03b ipsec.initd
-fd3cd27f9da9140fabd935377c3d6921 setup.patch"
-sha256sums="bdd3ccf31df1f3e8530887986ea8b6702a3db139486738213f5de8d8690b3723 openswan-2.6.38.tar.gz
-8595019c0ae7e1d00579c8d4ca2ba81b68e3be7b99f099b24e6ea1fd35b2bd7d openswan-libreswan-backport-949437-atodn.patch
-84a5e1c309ff707504a8b2f8ef47865adf6e3d9f0c60f3d1a19c5a8464bdfefb openswan-libreswan-backport-949437-do_3des.patch
-c36316a70d29553995cf89f7b4b2abcf0e05f1e35d725913cae6bfe161bb81a9 openswan-libreswan-backport-949437-do_aes.patch
-2390ab47cf5763c832dd9d652ff8ff6766547067502e1719031bac23b977d34a openswan-libreswan-backport-949437-x509dn.patch
-02fd160fb8d64f93a094c9f8a0912ed9cb47789601647f4a72ba3f736b220290 ipsec.initd
-6425c491cf1dc366e03e832a1d78bb2846f172ba6fe658b122707157099f9576 setup.patch"
-sha512sums="0963a9df548c901eb562185f97d844f57539668f11fbe2a43712223773053895c761b1d5d0be4fffa64014baf58ff2d7cf23676a3da51c5a5134b0639796ad10 openswan-2.6.38.tar.gz
-c670392e2e9968f0c9269c50858d24b5dc71126c3e066cbca9ceda53b16ad6fe892d4b32a58054a9cdfa14a81553a219098847b8c79ead00b6b8d05dbd18731d openswan-libreswan-backport-949437-atodn.patch
-14e466379a90c01f26997921c7e4967dfc76de1f58f7370e9755e04e1e351b8a7d8fad8b14af3f4a73d3358cc5271e4a89313aad239f12e92ab596c9d7dd0b02 openswan-libreswan-backport-949437-do_3des.patch
-3204d412bbd194ab49a6a5d465cbe38c0bc33266d096bc6bcc0cb6d4214fc05505eef0694036f40da4d2b56f9b50950cfe9816f1e4540431b49d859f7fb7e690 openswan-libreswan-backport-949437-do_aes.patch
-05c4a026b8baa91766717a58308cee0415403b1dc0632d805e36da906ec22b91c95b92ee701ca2b6d248f641f124d4ab32ed4fe7f42127aa6e3e308bf170ced3 openswan-libreswan-backport-949437-x509dn.patch
-7aefcc624b0e2a50e26f84db6197278c0633eeb38b064c613fbd635cbe606acd1e1280213db7c19f882d809d7eb6ea59a0c47e1b47dfe43de4f1c6deb08d38c4 ipsec.initd
-92152006ef3765c89d28462743bca25ab139c0205187bfb0a2c5992159e390939dc3f5f95c7ccb135d3ad674a756d776b7a7d7db903fd22994cf24478b7a71c8 setup.patch"
+md5sums="da2e8b02ecc30a408cc5766767fef84f openswan-2.6.41.tar.gz
+dab86e311bc22cefeda7506948557821 fix-natt.patch
+fd3cd27f9da9140fabd935377c3d6921 setup.patch
+f019d1fa23627d54462054fedc9de03b ipsec.initd"
+sha256sums="f9ebb395cb0f717dc43942662ab65161035a99dbf8e680c1d1511d4de130d0fb openswan-2.6.41.tar.gz
+f5857c3aab3797123d13daaf89bc70c74604364f7cfa9acb8db5e26738ed3b2d fix-natt.patch
+6425c491cf1dc366e03e832a1d78bb2846f172ba6fe658b122707157099f9576 setup.patch
+02fd160fb8d64f93a094c9f8a0912ed9cb47789601647f4a72ba3f736b220290 ipsec.initd"
+sha512sums="fd71703a0fc780ed35caac796006be242c93ac3eb3d849b4fbde96eba02be25da29119892c84f8cb487aaee87b6727b02b528aafa521ec402310489d9359edb8 openswan-2.6.41.tar.gz
+17c7d959401d2745aeea5551d12dd32a17d2714ae22738b9d52bfdf0d3b8e9ec06188dc867235680cfb3dd34ce0faa45f39f78d65ff0a6262d6bd94357665a97 fix-natt.patch
+92152006ef3765c89d28462743bca25ab139c0205187bfb0a2c5992159e390939dc3f5f95c7ccb135d3ad674a756d776b7a7d7db903fd22994cf24478b7a71c8 setup.patch
+7aefcc624b0e2a50e26f84db6197278c0633eeb38b064c613fbd635cbe606acd1e1280213db7c19f882d809d7eb6ea59a0c47e1b47dfe43de4f1c6deb08d38c4 ipsec.initd"
diff --git a/main/openswan/CVE-2013-2052.patch b/main/openswan/CVE-2013-2052.patch
deleted file mode 100644
index a34a67789b..0000000000
--- a/main/openswan/CVE-2013-2052.patch
+++ /dev/null
@@ -1,346 +0,0 @@
------BEGIN PGP SIGNED MESSAGE-----
-Hash: SHA256
-
-commit 7d0ca355a5c7f8337130d4b0b3e7686f2fa4d4c2
-Author: Paul Wouters <pwouters@redhat.com>
-Date: Thu Apr 25 12:44:55 2013 -0400
-
- * security: atodn() / atoid() buffer overflow
-
- lib/libswan/x509dn.c:atodn() does not perform any length checking
- whatsoever on the output buffer.
-
- Affected:
- - Libreswan 3.0 and 3.1 (3.2 disabled the oe= option)
- - Openswan versions up to and including 2.6.38
- - Possibly certain strongswan 3.x/4.x versions
-
- This overflow is exposed (pre-authentication) only in opportunistic
- encryption mode. When it is called via receiving a certificate
- via IKEv1 or IKEv2, and when it is loaded from disk, the buffers
- passed to atodn() are big enough.
-
- This means this vulnerability can only be triggered when:
- - Opportunistic Encryption is enabled (oe=yes)
- - The attacker is local in the same network and adds a malicious
- reverse DNS record to the client's IP, or
- - The attacker can trigger an OE DNS lookup to a client fully
- configured with OE and their own key.
-
- Libreswan and openswan versions do not enable Opportunistic Encryption
- per default. Most distributions like RHEL, Fedora, Debian and Ubuntu
- also do not enable OE per default.
-
- This patch addresses the vulnerability in atodn() and further limits the
- atoid() call not to traverse into the ASN1 case when triggered by non-cert
- cases such as opportunistic encryption.
-
- Vulnerability discoverd by Florian Weimer <fweimer@redhat.com> of the
- Red Hat Product Security Team.
-
- Patch by D. Hugh Redelmeier <hugh@mimosa.com> and Paul Wouters <pwouters@redhat.com>
-
-diff --git a/include/asn1.h b/include/asn1.h
-index d69ebf9..b812488 100644
-- --- a/include/asn1.h
-+++ b/include/asn1.h
-@@ -84,8 +84,10 @@ typedef enum {
- #define ASN1_BODY 0x20
- #define ASN1_RAW 0x40
-
-- -#define ASN1_INVALID_LENGTH 0xffffffff
-+#define ASN1_INVALID_LENGTH (~(size_t) 0) /* largest size_t */
-
-+#define ASN1_MAX_LEN (1U << (8*3)) /* don't handle objects with length greater than this */
-+#define ASN1_MAX_LEN_LEN 4 /* no coded length takes more than 4 bytes. */
-
- /* definition of an ASN.1 object */
-
-diff --git a/include/id.h b/include/id.h
-index d1825b4..b440a11 100644
-- --- a/include/id.h
-+++ b/include/id.h
-@@ -47,7 +47,7 @@ extern const struct id *resolve_myid(const struct id *id);
- extern void set_myFQDN(void);
- extern void free_myFQDN(void);
-
-- -extern err_t atoid(char *src, struct id *id, bool myid_ok);
-+extern err_t atoid(char *src, struct id *id, bool myid_ok, bool oe_only);
- extern void iptoid(const ip_address *ip, struct id *id);
- extern unsigned char* temporary_cyclic_buffer(void);
- extern int idtoa(const struct id *id, char *dst, size_t dstlen);
-diff --git a/lib/libswan/id.c b/lib/libswan/id.c
-index 4442971..31ca7e5 100644
-- --- a/lib/libswan/id.c
-+++ b/lib/libswan/id.c
-@@ -58,27 +58,29 @@ temporary_cyclic_buffer(void)
-
- /* Convert textual form of id into a (temporary) struct id.
- * Note that if the id is to be kept, unshare_id_content will be necessary.
-+ * This function should be split into parts so the boolean arguments can be
-+ * removed -- Paul
- */
- err_t
-- -atoid(char *src, struct id *id, bool myid_ok)
-+atoid(char *src, struct id *id, bool myid_ok, bool oe_only)
- {
- err_t ugh = NULL;
-
- *id = empty_id;
-
-- - if (myid_ok && streq("%myid", src))
-+ if (!oe_only && myid_ok && streq("%myid", src))
- {
- id->kind = ID_MYID;
- }
-- - else if (streq("%fromcert", src))
-+ else if (!oe_only && streq("%fromcert", src))
- {
- id->kind = ID_FROMCERT;
- }
-- - else if (streq("%none", src))
-+ else if (!oe_only && streq("%none", src))
- {
- id->kind = ID_NONE;
- }
-- - else if (strchr(src, '=') != NULL)
-+ else if (!oe_only && strchr(src, '=') != NULL)
- {
- /* we interpret this as an ASCII X.501 ID_DER_ASN1_DN */
- id->kind = ID_DER_ASN1_DN;
-@@ -112,7 +114,7 @@ atoid(char *src, struct id *id, bool myid_ok)
- {
- if (*src == '@')
- {
-- - if (*(src+1) == '#')
-+ if (!oe_only && *(src+1) == '#')
- {
- /* if there is a second specifier (#) on the line
- * we interprete this as ID_KEY_ID
-@@ -123,7 +125,7 @@ atoid(char *src, struct id *id, bool myid_ok)
- ugh = ttodata(src+2, 0, 16, (char *)id->name.ptr
- , strlen(src), &id->name.len);
- }
-- - else if (*(src+1) == '~')
-+ else if (!oe_only && *(src+1) == '~')
- {
- /* if there is a second specifier (~) on the line
- * we interprete this as a binary ID_DER_ASN1_DN
-@@ -134,7 +136,7 @@ atoid(char *src, struct id *id, bool myid_ok)
- ugh = ttodata(src+2, 0, 16, (char *)id->name.ptr
- , strlen(src), &id->name.len);
- }
-- - else if (*(src+1) == '[')
-+ else if (!oe_only && *(src+1) == '[')
- {
- /* if there is a second specifier ([) on the line
- * we interprete this as a text ID_KEY_ID, and we remove
-diff --git a/lib/libswan/secrets.c b/lib/libswan/secrets.c
-index 6e9466b..8ff80e0 100644
-- --- a/lib/libswan/secrets.c
-+++ b/lib/libswan/secrets.c
-@@ -1223,7 +1223,7 @@ lsw_process_secret_records(struct secret **psecrets, int verbose,
- }
- else
- {
-- - ugh = atoid(flp->tok, &id, FALSE);
-+ ugh = atoid(flp->tok, &id, FALSE, FALSE);
- }
-
- if (ugh != NULL)
-diff --git a/lib/libswan/x509dn.c b/lib/libswan/x509dn.c
-index 61407e5..7731856 100644
-- --- a/lib/libswan/x509dn.c
-+++ b/lib/libswan/x509dn.c
-@@ -472,7 +472,7 @@ static const x501rdn_t x501rdns[] = {
- {"TCGID" , {oid_TCGID, 12}, ASN1_PRINTABLESTRING}
- };
-
-- -#define X501_RDN_ROOF 24
-+#define X501_RDN_ROOF elemsof(x501rdns)
-
- /* Maximum length of ASN.1 distinquished name */
- #define ASN1_BUF_LEN 512
-@@ -775,11 +775,11 @@ atodn(char *src, chunk_t *dn)
- UNKNOWN_OID = 4
- } state_t;
-
-- - u_char oid_len_buf[3];
-- - u_char name_len_buf[3];
-- - u_char rdn_seq_len_buf[3];
-- - u_char rdn_set_len_buf[3];
-- - u_char dn_seq_len_buf[3];
-+ u_char oid_len_buf[ASN1_MAX_LEN_LEN];
-+ u_char name_len_buf[ASN1_MAX_LEN_LEN];
-+ u_char rdn_seq_len_buf[ASN1_MAX_LEN_LEN];
-+ u_char rdn_set_len_buf[ASN1_MAX_LEN_LEN];
-+ u_char dn_seq_len_buf[ASN1_MAX_LEN_LEN];
-
- chunk_t asn1_oid_len = { oid_len_buf, 0 };
- chunk_t asn1_name_len = { name_len_buf, 0 };
-@@ -797,7 +797,7 @@ atodn(char *src, chunk_t *dn)
-
- err_t ugh = NULL;
-
-- - u_char *dn_ptr = dn->ptr + 4;
-+ u_char *dn_ptr = dn->ptr + 1 + ASN1_MAX_LEN_LEN; /* leave room for prefix */
-
- state_t state = SEARCH_OID;
-
-@@ -885,25 +885,37 @@ atodn(char *src, chunk_t *dn)
- code_asn1_length(rdn_set_len, &asn1_rdn_set_len);
-
- /* encode the relative distinguished name */
-- - *dn_ptr++ = ASN1_SET;
-- - chunkcpy(dn_ptr, asn1_rdn_set_len);
-- - *dn_ptr++ = ASN1_SEQUENCE;
-- - chunkcpy(dn_ptr, asn1_rdn_seq_len);
-- - *dn_ptr++ = ASN1_OID;
-- - chunkcpy(dn_ptr, asn1_oid_len);
-- - chunkcpy(dn_ptr, x501rdns[pos].oid);
-- - /* encode the ASN.1 character string type of the name */
-- - *dn_ptr++ = (x501rdns[pos].type == ASN1_PRINTABLESTRING
-- - && !is_printablestring(name))? ASN1_T61STRING : x501rdns[pos].type;
-- - chunkcpy(dn_ptr, asn1_name_len);
-- - chunkcpy(dn_ptr, name);
-- -
-- - /* accumulate the length of the distinguished name sequence */
-- - dn_seq_len += 1 + asn1_rdn_set_len.len + rdn_set_len;
-- -
-- - /* reset name and change state */
-- - name = empty_chunk;
-- - state = SEARCH_OID;
-+ if (IDTOA_BUF < dn_ptr - dn->ptr
-+ + 1 + asn1_rdn_set_len.len /* set */
-+ + 1 + asn1_rdn_seq_len.len /* sequence */
-+ + 1 + asn1_oid_len.len + x501rdns[pos].oid.len /* oid len, oid */
-+ + 1 + asn1_name_len.len + name.len /* type name */
-+ ) {
-+ /* no room! */
-+ ugh = "DN is too big";
-+ state = UNKNOWN_OID;
-+ /* I think that it is safe to continue (but perhaps pointless) */
-+ } else {
-+ *dn_ptr++ = ASN1_SET;
-+ chunkcpy(dn_ptr, asn1_rdn_set_len);
-+ *dn_ptr++ = ASN1_SEQUENCE;
-+ chunkcpy(dn_ptr, asn1_rdn_seq_len);
-+ *dn_ptr++ = ASN1_OID;
-+ chunkcpy(dn_ptr, asn1_oid_len);
-+ chunkcpy(dn_ptr, x501rdns[pos].oid);
-+ /* encode the ASN.1 character string type of the name */
-+ *dn_ptr++ = (x501rdns[pos].type == ASN1_PRINTABLESTRING
-+ && !is_printablestring(name))? ASN1_T61STRING : x501rdns[pos].type;
-+ chunkcpy(dn_ptr, asn1_name_len);
-+ chunkcpy(dn_ptr, name);
-+
-+ /* accumulate the length of the distinguished name sequence */
-+ dn_seq_len += 1 + asn1_rdn_set_len.len + rdn_set_len;
-+
-+ /* reset name and change state */
-+ name = empty_chunk;
-+ state = SEARCH_OID;
-+ }
- }
- break;
- case UNKNOWN_OID:
-@@ -911,9 +923,9 @@ atodn(char *src, chunk_t *dn)
- }
- } while (*src++ != '\0');
-
-- - /* complete the distinguished name sequence*/
-- - code_asn1_length(dn_seq_len, &asn1_dn_seq_len);
-- - dn->ptr += 3 - asn1_dn_seq_len.len;
-+ /* complete the distinguished name sequence: prefix it with ASN1_SEQUENCE and length */
-+ code_asn1_length((size_t)dn_seq_len, &asn1_dn_seq_len);
-+ dn->ptr += ASN1_MAX_LEN_LEN + 1 - 1 - asn1_dn_seq_len.len;
- dn->len = 1 + asn1_dn_seq_len.len + dn_seq_len;
- dn_ptr = dn->ptr;
- *dn_ptr++ = ASN1_SEQUENCE;
-diff --git a/programs/pluto/connections.c b/programs/pluto/connections.c
-index e8d326b..f08521b 100644
-- --- a/programs/pluto/connections.c
-+++ b/programs/pluto/connections.c
-@@ -911,7 +911,7 @@ extract_end(struct end *dst, const struct whack_end *src, const char *which)
- }
- else
- {
-- - err_t ugh = atoid(src->id, &dst->id, TRUE);
-+ err_t ugh = atoid(src->id, &dst->id, TRUE, FALSE);
-
- if (ugh != NULL)
- {
-diff --git a/programs/pluto/dnskey.c b/programs/pluto/dnskey.c
-index 5525d12..78f1d0a 100644
-- --- a/programs/pluto/dnskey.c
-+++ b/programs/pluto/dnskey.c
-@@ -277,8 +277,12 @@ decode_iii(char **pp, struct id *gw_id)
- if (*p == '@')
- {
- /* gateway specification in this record is @FQDN */
-- - err_t ugh = atoid(p, gw_id, FALSE);
-
-+ if(strspn(p,' ') >= IDTOA_BUF) {
-+ return builddiag("malformed FQDN in TXT " our_TXT_attr_string ": ID too large for IDTOA_BUF");
-+ }
-+
-+ err_t ugh = atoid(p, gw_id, FALSE, TRUE); /* only run OE related parts of atoid() */
- if (ugh != NULL)
- return builddiag("malformed FQDN in TXT " our_TXT_attr_string ": %s"
- , ugh);
-diff --git a/programs/pluto/myid.c b/programs/pluto/myid.c
-index bdd0e12..2e92f25 100644
-- --- a/programs/pluto/myid.c
-+++ b/programs/pluto/myid.c
-@@ -103,7 +103,7 @@ set_myid(enum myid_state s, char *idstr)
- if (idstr != NULL)
- {
- struct id id;
-- - err_t ugh = atoid(idstr, &id, FALSE);
-+ err_t ugh = atoid(idstr, &id, FALSE, FALSE);
-
- if (ugh != NULL)
- {
-diff --git a/programs/pluto/rcv_whack.c b/programs/pluto/rcv_whack.c
-index 1725357..7d5072c 100644
-- --- a/programs/pluto/rcv_whack.c
-+++ b/programs/pluto/rcv_whack.c
-@@ -259,7 +259,7 @@ static void
- key_add_request(const struct whack_message *msg)
- {
- struct id keyid;
-- - err_t ugh = atoid(msg->keyid, &keyid, FALSE);
-+ err_t ugh = atoid(msg->keyid, &keyid, FALSE, FALSE);
-
- if (ugh != NULL)
- {
-diff --git a/programs/showhostkey/showhostkey.c b/programs/showhostkey/showhostkey.c
-index c9fe9cf..bf87080 100644
-- --- a/programs/showhostkey/showhostkey.c
-+++ b/programs/showhostkey/showhostkey.c
-@@ -203,7 +203,7 @@ struct secret *pick_key(struct secret *host_secrets
- struct secret *s;
- err_t e;
-
-- - e = atoid(idname, &id, FALSE);
-+ e = atoid(idname, &id, FALSE, FALSE);
- if(e) {
- printf("%s: key '%s' is invalid\n", progname, idname);
- exit(4);
------BEGIN PGP SIGNATURE-----
-Version: GnuPG v1.4.13 (GNU/Linux)
-
-iQIcBAEBCAAGBQJRkWmnAAoJEIX/S0OzD8b5EZIP+wb5LyvL4jXGYJzvalkCjWL3
-1cZp5H672jGdVvW/G3bJ5unhjpRt9ASxebHR/4LfWZuWG5U4gdPRjcz1YcuNwVnB
-xOXZ4ELWYRFFblkkHz+GO5rSRwmWhFnyGvDdN5Oh6VBcmegHvaKk6uVLPXZJpVdg
-2U1+s+x3EkrcP6IJyTa9pyhZiDWcdYVn3seyHcFCNa3R/Xkwefi3HwA2w8+L18NX
-NvIMUx2aXj70cBE5VAg+XJWIZ2Rrlf2zHDM96GUUfGIIH1mzpuxYCFbpGqISmOYI
-AAumQ9I4kQGy0ZkWn41Et3ppJvcRFoMlAz70Ay+nbZ/+eqQH9B3KfplfX2UrsXAn
-SVvMPypkMfjhUbPG8AWr//6+a0uZxa0PyibNXhhdr+3ocANaZ8ty+ehFmVl0DIBM
-rc582erQ8s4Bj8v+4vy1TzkR5HXWhwWhCjD0EnU8zGGjZ2u+1BAYgzTUG4Nqo+/Q
-ziJdc71vy+OqyLXTFMdekUuRl40BXuFHHUv6jWeslgIh2/1Z/A0NZzxs2sMFCkEW
-anTG32ridJSCqQhSXZ4xW07O5F45csH6qgze2jQdYEizATYsDqeKazEZhmakUsow
-v5gj85f5VYGWjoYjKr/HbrueEbeGpV3Twf4tZ6XyCxAjJEt6N8XWidSiMeL3gNIm
-cgXmYH+ak4nDLJGyaYDt
-=5y9o
------END PGP SIGNATURE-----
diff --git a/main/openswan/fix-natt.patch b/main/openswan/fix-natt.patch
new file mode 100644
index 0000000000..308bac816e
--- /dev/null
+++ b/main/openswan/fix-natt.patch
@@ -0,0 +1,39 @@
+https://github.com/xelerance/Openswan/commit/b6041cb5d1d07974596be79606a977e88dd9ec48.patch
+
+From b6041cb5d1d07974596be79606a977e88dd9ec48 Mon Sep 17 00:00:00 2001
+From: Patrick Naubert <patrickn@xelerance.com>
+Date: Fri, 28 Feb 2014 19:59:54 -0500
+Subject: [PATCH] Bring back NAT traversal that got mistakenly pulled out by
+ CVE-2014-2037 patch. Patch by Thomas Geulig
+
+---
+ lib/libopenswan/constants.c | 11 ++++++++++-
+ 1 file changed, 10 insertions(+), 1 deletion(-)
+
+diff --git a/lib/libopenswan/constants.c b/lib/libopenswan/constants.c
+index 932b205..09f7e80 100644
+--- a/lib/libopenswan/constants.c
++++ b/lib/libopenswan/constants.c
+@@ -167,9 +167,18 @@ const char *const payload_name_ikev2_main[] = {
+ NULL /* termination for bitnamesof() */
+ };
+
++const char *const payload_name_nat_d[] = {
++ "ISAKMP_NEXT_NAT-D",
++ "ISAKMP_NEXT_NAT-OA",
++ NULL
++};
++
++static enum_names payload_names_nat_d =
++{ ISAKMP_NEXT_NATD_DRAFTS, ISAKMP_NEXT_NATOA_DRAFTS, payload_name_nat_d, NULL };
++
+ static enum_names payload_names_ikev2_main =
+ { ISAKMP_NEXT_v2SA, ISAKMP_NEXT_v2EAP, payload_name_ikev2_main,
+- NULL };
++ &payload_names_nat_d };
+
+ const char *const payload_name_ikev2[] = {
+ "ISAKMP_NEXT_v2NONE", /* 33 */
+--
+1.9.1
+
diff --git a/main/openswan/openswan-libreswan-backport-949437-atodn.patch b/main/openswan/openswan-libreswan-backport-949437-atodn.patch
deleted file mode 100644
index 524a75b20f..0000000000
--- a/main/openswan/openswan-libreswan-backport-949437-atodn.patch
+++ /dev/null
@@ -1,278 +0,0 @@
-diff -Naur openswan-2.6.32-orig/include/asn1.h openswan-2.6.32/include/asn1.h
---- openswan-2.6.32-orig/include/asn1.h 2010-12-17 20:23:54.000000000 -0500
-+++ openswan-2.6.32/include/asn1.h 2013-04-24 13:11:05.799140126 -0400
-@@ -84,8 +84,10 @@
- #define ASN1_BODY 0x20
- #define ASN1_RAW 0x40
-
--#define ASN1_INVALID_LENGTH 0xffffffff
-+#define ASN1_INVALID_LENGTH (~(size_t) 0) /* largest size_t */
-
-+#define ASN1_MAX_LEN (1U << (8*3)) /* don't handle objects with length greater than this */
-+#define ASN1_MAX_LEN_LEN 4 /* no coded length takes more than 4 bytes. */
-
- /* definition of an ASN.1 object */
-
-diff -Naur openswan-2.6.32-orig/include/id.h openswan-2.6.32/include/id.h
---- openswan-2.6.32-orig/include/id.h 2010-12-17 20:23:54.000000000 -0500
-+++ openswan-2.6.32/include/id.h 2013-04-24 13:11:05.799140126 -0400
-@@ -46,7 +46,7 @@
- extern const struct id *resolve_myid(const struct id *id);
- extern void set_myFQDN(void);
-
--extern err_t atoid(char *src, struct id *id, bool myid_ok);
-+extern err_t atoid(char *src, struct id *id, bool myid_ok, bool oe_only);
- extern void iptoid(const ip_address *ip, struct id *id);
- extern unsigned char* temporary_cyclic_buffer(void);
- extern int idtoa(const struct id *id, char *dst, size_t dstlen);
-diff -Naur openswan-2.6.32-orig/lib/libopenswan/id.c openswan-2.6.32/lib/libopenswan/id.c
---- openswan-2.6.32-orig/lib/libopenswan/id.c 2010-12-17 20:23:54.000000000 -0500
-+++ openswan-2.6.32/lib/libopenswan/id.c 2013-04-24 13:11:05.799140126 -0400
-@@ -57,27 +57,29 @@
-
- /* Convert textual form of id into a (temporary) struct id.
- * Note that if the id is to be kept, unshare_id_content will be necessary.
-+ * This function should be split into parts so the boolean arguments can be
-+ * removed -- Paul
- */
- err_t
--atoid(char *src, struct id *id, bool myid_ok)
-+atoid(char *src, struct id *id, bool myid_ok, bool oe_only)
- {
- err_t ugh = NULL;
-
- *id = empty_id;
-
-- if (myid_ok && streq("%myid", src))
-+ if (!oe_only && myid_ok && streq("%myid", src))
- {
- id->kind = ID_MYID;
- }
-- else if (streq("%fromcert", src))
-+ else if (!oe_only && streq("%fromcert", src))
- {
- id->kind = ID_FROMCERT;
- }
-- else if (streq("%none", src))
-+ else if (!oe_only && streq("%none", src))
- {
- id->kind = ID_NONE;
- }
-- else if (strchr(src, '=') != NULL)
-+ else if (!oe_only && strchr(src, '=') != NULL)
- {
- /* we interpret this as an ASCII X.501 ID_DER_ASN1_DN */
- id->kind = ID_DER_ASN1_DN;
-@@ -111,7 +113,7 @@
- {
- if (*src == '@')
- {
-- if (*(src+1) == '#')
-+ if (!oe_only && *(src+1) == '#')
- {
- /* if there is a second specifier (#) on the line
- * we interprete this as ID_KEY_ID
-@@ -122,7 +124,7 @@
- ugh = ttodata(src+2, 0, 16, (char *)id->name.ptr
- , strlen(src), &id->name.len);
- }
-- else if (*(src+1) == '~')
-+ else if (!oe_only && *(src+1) == '~')
- {
- /* if there is a second specifier (~) on the line
- * we interprete this as a binary ID_DER_ASN1_DN
-@@ -133,7 +135,7 @@
- ugh = ttodata(src+2, 0, 16, (char *)id->name.ptr
- , strlen(src), &id->name.len);
- }
-- else if (*(src+1) == '[')
-+ else if (!oe_only && *(src+1) == '[')
- {
- /* if there is a second specifier ([) on the line
- * we interprete this as a text ID_KEY_ID, and we remove
-diff -Naur openswan-2.6.32-orig/lib/libopenswan/secrets.c openswan-2.6.32/lib/libopenswan/secrets.c
---- openswan-2.6.32-orig/lib/libopenswan/secrets.c 2010-12-17 20:23:54.000000000 -0500
-+++ openswan-2.6.32/lib/libopenswan/secrets.c 2013-04-24 13:11:05.800140140 -0400
-@@ -1299,7 +1299,7 @@
- }
- else
- {
-- ugh = atoid(flp->tok, &id, FALSE);
-+ ugh = atoid(flp->tok, &id, FALSE, FALSE);
- }
-
- if (ugh != NULL)
-diff -Naur openswan-2.6.32-orig/lib/libopenswan/x509dn.c openswan-2.6.32/lib/libopenswan/x509dn.c
---- openswan-2.6.32-orig/lib/libopenswan/x509dn.c 2010-12-17 20:23:54.000000000 -0500
-+++ openswan-2.6.32/lib/libopenswan/x509dn.c 2013-04-24 13:11:05.801140153 -0400
-@@ -476,7 +476,7 @@
- {"TCGID" , {oid_TCGID, 12}, ASN1_PRINTABLESTRING}
- };
-
--#define X501_RDN_ROOF 24
-+#define X501_RDN_ROOF elemsof(x501rdns)
-
- /* Maximum length of ASN.1 distinquished name */
- #define ASN1_BUF_LEN 512
-@@ -746,11 +746,11 @@
- UNKNOWN_OID = 4
- } state_t;
-
-- u_char oid_len_buf[3];
-- u_char name_len_buf[3];
-- u_char rdn_seq_len_buf[3];
-- u_char rdn_set_len_buf[3];
-- u_char dn_seq_len_buf[3];
-+ u_char oid_len_buf[ASN1_MAX_LEN_LEN];
-+ u_char name_len_buf[ASN1_MAX_LEN_LEN];
-+ u_char rdn_seq_len_buf[ASN1_MAX_LEN_LEN];
-+ u_char rdn_set_len_buf[ASN1_MAX_LEN_LEN];
-+ u_char dn_seq_len_buf[ASN1_MAX_LEN_LEN];
-
- chunk_t asn1_oid_len = { oid_len_buf, 0 };
- chunk_t asn1_name_len = { name_len_buf, 0 };
-@@ -768,7 +768,7 @@
-
- err_t ugh = NULL;
-
-- u_char *dn_ptr = dn->ptr + 4;
-+ u_char *dn_ptr = dn->ptr + 1 + ASN1_MAX_LEN_LEN; /* leave room for prefix */
-
- state_t state = SEARCH_OID;
-
-@@ -841,25 +841,37 @@
- code_asn1_length(rdn_set_len, &asn1_rdn_set_len);
-
- /* encode the relative distinguished name */
-- *dn_ptr++ = ASN1_SET;
-- chunkcpy(dn_ptr, asn1_rdn_set_len);
-- *dn_ptr++ = ASN1_SEQUENCE;
-- chunkcpy(dn_ptr, asn1_rdn_seq_len);
-- *dn_ptr++ = ASN1_OID;
-- chunkcpy(dn_ptr, asn1_oid_len);
-- chunkcpy(dn_ptr, x501rdns[pos].oid);
-- /* encode the ASN.1 character string type of the name */
-- *dn_ptr++ = (x501rdns[pos].type == ASN1_PRINTABLESTRING
-- && !is_printablestring(name))? ASN1_T61STRING : x501rdns[pos].type;
-- chunkcpy(dn_ptr, asn1_name_len);
-- chunkcpy(dn_ptr, name);
--
-- /* accumulate the length of the distinguished name sequence */
-- dn_seq_len += 1 + asn1_rdn_set_len.len + rdn_set_len;
--
-- /* reset name and change state */
-- name = empty_chunk;
-- state = SEARCH_OID;
-+ if (IDTOA_BUF < dn_ptr - dn->ptr
-+ + 1 + asn1_rdn_set_len.len /* set */
-+ + 1 + asn1_rdn_seq_len.len /* sequence */
-+ + 1 + asn1_oid_len.len + x501rdns[pos].oid.len /* oid len, oid */
-+ + 1 + asn1_name_len.len + name.len /* type name */
-+ ) {
-+ /* no room! */
-+ ugh = "DN is too big";
-+ state = UNKNOWN_OID;
-+ /* I think that it is safe to continue (but perhaps pointless) */
-+ } else {
-+ *dn_ptr++ = ASN1_SET;
-+ chunkcpy(dn_ptr, asn1_rdn_set_len);
-+ *dn_ptr++ = ASN1_SEQUENCE;
-+ chunkcpy(dn_ptr, asn1_rdn_seq_len);
-+ *dn_ptr++ = ASN1_OID;
-+ chunkcpy(dn_ptr, asn1_oid_len);
-+ chunkcpy(dn_ptr, x501rdns[pos].oid);
-+ /* encode the ASN.1 character string type of the name */
-+ *dn_ptr++ = (x501rdns[pos].type == ASN1_PRINTABLESTRING
-+ && !is_printablestring(name))? ASN1_T61STRING : x501rdns[pos].type;
-+ chunkcpy(dn_ptr, asn1_name_len);
-+ chunkcpy(dn_ptr, name);
-+
-+ /* accumulate the length of the distinguished name sequence */
-+ dn_seq_len += 1 + asn1_rdn_set_len.len + rdn_set_len;
-+
-+ /* reset name and change state */
-+ name = empty_chunk;
-+ state = SEARCH_OID;
-+ }
- }
- break;
- case UNKNOWN_OID:
-@@ -867,9 +879,10 @@
- }
- } while (*src++ != '\0');
-
-- /* complete the distinguished name sequence*/
-- code_asn1_length(dn_seq_len, &asn1_dn_seq_len);
-- dn->ptr += 3 - asn1_dn_seq_len.len;
-+ /* complete the distinguished name sequence: prefix it with ASN1_SEQUENCE and length */
-+
-+ code_asn1_length((size_t)dn_seq_len, &asn1_dn_seq_len);
-+ dn->ptr += ASN1_MAX_LEN_LEN + 1 - 1 - asn1_dn_seq_len.len;
- dn->len = 1 + asn1_dn_seq_len.len + dn_seq_len;
- dn_ptr = dn->ptr;
- *dn_ptr++ = ASN1_SEQUENCE;
-diff -Naur openswan-2.6.32-orig/programs/pluto/connections.c openswan-2.6.32/programs/pluto/connections.c
---- openswan-2.6.32-orig/programs/pluto/connections.c 2013-04-24 13:10:30.520656796 -0400
-+++ openswan-2.6.32/programs/pluto/connections.c 2013-04-24 13:11:05.802140167 -0400
-@@ -891,7 +891,7 @@
- }
- else
- {
-- err_t ugh = atoid(src->id, &dst->id, TRUE);
-+ err_t ugh = atoid(src->id, &dst->id, TRUE, FALSE);
-
- if (ugh != NULL)
- {
-diff -Naur openswan-2.6.32-orig/programs/pluto/dnskey.c openswan-2.6.32/programs/pluto/dnskey.c
---- openswan-2.6.32-orig/programs/pluto/dnskey.c 2010-12-17 20:23:54.000000000 -0500
-+++ openswan-2.6.32/programs/pluto/dnskey.c 2013-04-24 13:11:05.803140181 -0400
-@@ -289,8 +289,12 @@
- if (*p == '@')
- {
- /* gateway specification in this record is @FQDN */
-- err_t ugh = atoid(p, gw_id, FALSE);
-
-+ if(strspn(p," ") >= IDTOA_BUF) {
-+ return builddiag("malformed FQDN in TXT " our_TXT_attr_string ": ID too large for IDTOA_BUF");
-+ }
-+
-+ err_t ugh = atoid(p, gw_id, FALSE, TRUE); /* only run OE related parts of atoid() */
- if (ugh != NULL)
- return builddiag("malformed FQDN in TXT " our_TXT_attr_string ": %s"
- , ugh);
-diff -Naur openswan-2.6.32-orig/programs/pluto/myid.c openswan-2.6.32/programs/pluto/myid.c
---- openswan-2.6.32-orig/programs/pluto/myid.c 2010-12-17 20:23:54.000000000 -0500
-+++ openswan-2.6.32/programs/pluto/myid.c 2013-04-24 13:11:05.803140181 -0400
-@@ -103,7 +103,7 @@
- if (idstr != NULL)
- {
- struct id id;
-- err_t ugh = atoid(idstr, &id, FALSE);
-+ err_t ugh = atoid(idstr, &id, FALSE, FALSE);
-
- if (ugh != NULL)
- {
-diff -Naur openswan-2.6.32-orig/programs/pluto/rcv_whack.c openswan-2.6.32/programs/pluto/rcv_whack.c
---- openswan-2.6.32-orig/programs/pluto/rcv_whack.c 2013-04-24 13:10:30.392655041 -0400
-+++ openswan-2.6.32/programs/pluto/rcv_whack.c 2013-04-24 13:11:05.803140181 -0400
-@@ -243,7 +243,7 @@
- key_add_request(const struct whack_message *msg)
- {
- struct id keyid;
-- err_t ugh = atoid(msg->keyid, &keyid, FALSE);
-+ err_t ugh = atoid(msg->keyid, &keyid, FALSE, FALSE);
-
- if (ugh != NULL)
- {
-diff -Naur openswan-2.6.32-orig/programs/showhostkey/showhostkey.c openswan-2.6.32/programs/showhostkey/showhostkey.c
---- openswan-2.6.32-orig/programs/showhostkey/showhostkey.c 2010-12-17 20:23:54.000000000 -0500
-+++ openswan-2.6.32/programs/showhostkey/showhostkey.c 2013-04-24 13:11:05.804140194 -0400
-@@ -208,7 +208,7 @@
- struct secret *s;
- err_t e;
-
-- e = atoid(idname, &id, FALSE);
-+ e = atoid(idname, &id, FALSE, FALSE);
- if(e) {
- printf("%s: key '%s' is invalid\n", progname, idname);
- exit(4);
diff --git a/main/openswan/openswan-libreswan-backport-949437-do_3des.patch b/main/openswan/openswan-libreswan-backport-949437-do_3des.patch
deleted file mode 100644
index 75dbe3b636..0000000000
--- a/main/openswan/openswan-libreswan-backport-949437-do_3des.patch
+++ /dev/null
@@ -1,61 +0,0 @@
-From acdd65497d164082e0462b3f2d4407f0c50ccf71 Mon Sep 17 00:00:00 2001
-From: Florian Weimer <fweimer@redhat.com>
-Date: Wed, 10 Apr 2013 10:32:52 +0200
-Subject: [PATCH 06/10] do_3des: Abort on failure
-
-The routine cannot signal encryption failures to the caller
-and would leave the buffer unencrypted on error.
----
- lib/libopenswan/pem.c | 14 ++++++++++----
- 1 file changed, 10 insertions(+), 4 deletions(-)
-
-diff --git a/lib/libopenswan/pem.c b/lib/libopenswan/pem.c
-index 36da401..d42655a 100644
---- a/lib/libopenswan/pem.c
-+++ b/lib/libopenswan/pem.c
-@@ -483,7 +483,7 @@ void do_3des_nss(u_int8_t *buf, size_t buf_len
- memcpy(&symkey, key, key_size);
- if (symkey == NULL) {
- loglog(RC_LOG_SERIOUS, "do_3des: NSS derived enc key is NULL \n");
-- goto out;
-+ abort();
- }
-
- ivitem.type = siBuffer;
-@@ -493,7 +493,7 @@ void do_3des_nss(u_int8_t *buf, size_t buf_len
- secparam = PK11_ParamFromIV(ciphermech, &ivitem);
- if (secparam == NULL) {
- loglog(RC_LOG_SERIOUS, "do_3des: Failure to set up PKCS11 param (err %d)\n",PR_GetError());
-- goto out;
-+ abort();
- }
-
- outlen = 0;
-@@ -505,8 +505,15 @@ void do_3des_nss(u_int8_t *buf, size_t buf_len
- }
-
- enccontext = PK11_CreateContextBySymKey(ciphermech, enc? CKA_ENCRYPT: CKA_DECRYPT, symkey, secparam);
-+ if (enccontext == NULL) {
-+ loglog(RC_LOG_SERIOUS, "do_3des: PKCS11 context creation failure (err %d)\n", PR_GetError());
-+ abort();
-+ }
- rv = PK11_CipherOp(enccontext, tmp_buf, &outlen, buf_len, buf, buf_len);
-- passert(rv==SECSuccess);
-+ if (rv != SECSuccess) {
-+ loglog(RC_LOG_SERIOUS, "do_3des: PKCS11 operation failure (err %d)\n", PR_GetError());
-+ abort();
-+ }
-
- if(enc) {
- memcpy(new_iv, (char*) tmp_buf + buf_len-DES_CBC_BLOCK_SIZE, DES_CBC_BLOCK_SIZE);
-@@ -518,7 +525,6 @@ void do_3des_nss(u_int8_t *buf, size_t buf_len
- PR_Free(tmp_buf);
- PR_Free(new_iv);
-
--out:
- if (secparam) {
- SECITEM_FreeItem(secparam, PR_TRUE);
- }
---
-1.8.1.4
-
diff --git a/main/openswan/openswan-libreswan-backport-949437-do_aes.patch b/main/openswan/openswan-libreswan-backport-949437-do_aes.patch
deleted file mode 100644
index aedb4d34ab..0000000000
--- a/main/openswan/openswan-libreswan-backport-949437-do_aes.patch
+++ /dev/null
@@ -1,62 +0,0 @@
-From ee267f812f6d72da400cc24265c399c3e9048a8a Mon Sep 17 00:00:00 2001
-From: Florian Weimer <fweimer@redhat.com>
-Date: Wed, 10 Apr 2013 10:33:02 +0200
-Subject: [PATCH 07/10] do_aes: Abort on failure
-
-The routine cannot signal encryption failures to the caller
-and would leave the buffer unencrypted on error.
----
- programs/pluto/ike_alg_aes.c | 15 ++++++++++-----
- 1 file changed, 10 insertions(+), 5 deletions(-)
-
-diff --git a/programs/pluto/ike_alg_aes.c b/programs/pluto/ike_alg_aes.c
-index 1d4aada..95999bb 100644
---- a/programs/pluto/ike_alg_aes.c
-+++ b/programs/pluto/ike_alg_aes.c
-@@ -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 *
-
- if (symkey == NULL) {
- loglog(RC_LOG_SERIOUS, "do_aes: NSS derived enc key in NULL\n");
-- goto out;
-+ abort();
- }
-
- ivitem.type = siBuffer;
-@@ -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 *
- secparam = PK11_ParamFromIV(ciphermech, &ivitem);
- if (secparam == NULL) {
- loglog(RC_LOG_SERIOUS, "do_aes: Failure to set up PKCS11 param (err %d)\n",PR_GetError());
-- goto out;
-+ abort();
- }
-
- outlen = 0;
-@@ -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 *
- }
-
- enccontext = PK11_CreateContextBySymKey(ciphermech, enc? CKA_ENCRYPT : CKA_DECRYPT, symkey, secparam);
-+ if (enccontext == NULL) {
-+ loglog(RC_LOG_SERIOUS, "do_aes: PKCS11 context creation failure (err %d)\n", PR_GetError());
-+ abort();
-+ }
- rv = PK11_CipherOp(enccontext, tmp_buf, &outlen, buf_len, buf, buf_len);
-- passert(rv==SECSuccess);
-+ if (rv != SECSuccess) {
-+ loglog(RC_LOG_SERIOUS, "do_aes: PKCS11 operation failure (err %d)\n", PR_GetError());
-+ abort();
-+ }
- PK11_DestroyContext(enccontext, PR_TRUE);
- memcpy(buf,tmp_buf,buf_len);
-
-@@ -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 *
- memcpy(iv, new_iv, AES_CBC_BLOCK_SIZE);
- PR_Free(tmp_buf);
-
--out:
--
- if (secparam)
- SECITEM_FreeItem(secparam, PR_TRUE);
- DBG(DBG_CRYPT, DBG_log("NSS do_aes: exit"));
---
-1.8.1.4
-
diff --git a/main/openswan/openswan-libreswan-backport-949437-x509dn.patch b/main/openswan/openswan-libreswan-backport-949437-x509dn.patch
deleted file mode 100644
index 2d41293771..0000000000
--- a/main/openswan/openswan-libreswan-backport-949437-x509dn.patch
+++ /dev/null
@@ -1,79 +0,0 @@
-diff --git a/lib/libopenswan/x509dn.c b/lib/libopenswan/x509dn.c
-index 7731856..43c4bb5 100644
---- a/lib/libopenswan/x509dn.c
-+++ b/lib/libopenswan/x509dn.c
-@@ -477,11 +477,25 @@ static const x501rdn_t x501rdns[] = {
- /* Maximum length of ASN.1 distinquished name */
- #define ASN1_BUF_LEN 512
-
-+static void format_chunk(chunk_t *ch, const char *format, ...) PRINTF_LIKE(2);
-+
- static void
--update_chunk(chunk_t *ch, int n)
-+format_chunk(chunk_t *ch, const char *format, ...)
- {
-- n = (n > -1 && n < (int)ch->len)? n : (int)ch->len-1;
-- ch->ptr += n; ch->len -= n;
-+ if (ch->len > 0) {
-+ size_t len = ch->len;
-+ va_list args;
-+ va_start(args, format);
-+ int ret = vsnprintf((char *)ch->ptr, len, format, args);
-+ va_end(args);
-+ if (ret < 0 || ret > len) {
-+ ch->ptr += len;
-+ ch->len = 0;
-+ } else {
-+ ch->ptr += ret;
-+ ch->len -= ret;
-+ }
-+ }
- }
-
-
-@@ -612,9 +626,7 @@ dn_parse(chunk_t dn, chunk_t *str)
- err_t ugh;
-
- if(dn.ptr == NULL) {
-- const char *e = "(empty)";
-- strncpy((char *)str->ptr, e, str->len);
-- update_chunk(str, strlen(e));
-+ format_chunk(str, "(empty)");
- return NULL;
- }
- ugh = init_rdn(dn, &rdn, &attribute, &next);
-@@ -632,19 +644,17 @@ dn_parse(chunk_t dn, chunk_t *str)
- if (first) /* first OID/value pair */
- first = FALSE;
- else /* separate OID/value pair by a comma */
-- update_chunk(str, snprintf((char *)str->ptr,str->len,", "));
-+ format_chunk(str, ", ");
-
- /* print OID */
- oid_code = known_oid(oid);
- if (oid_code == OID_UNKNOWN) /* OID not found in list */
- hex_str(oid, str);
- else
-- update_chunk(str, snprintf((char *)str->ptr,str->len,"%s",
-- oid_names[oid_code].name));
-+ format_chunk(str, "%s", oid_names[oid_code].name);
-
- /* print value */
-- update_chunk(str, snprintf((char *)str->ptr,str->len,"=%.*s",
-- (int)value.len,value.ptr));
-+ format_chunk(str, "=%.*s", (int)value.len, value.ptr);
- }
- return NULL;
- }
-@@ -684,9 +694,9 @@ void
- hex_str(chunk_t bin, chunk_t *str)
- {
- u_int i;
-- update_chunk(str, snprintf((char *)str->ptr,str->len,"0x"));
-+ format_chunk(str, "0x");
- for (i=0; i < bin.len; i++)
-- update_chunk(str, snprintf((char *)str->ptr,str->len,"%02X",*bin.ptr++));
-+ format_chunk(str, "%02X", *bin.ptr++);
- }
-
-