summaryrefslogtreecommitdiffstats
path: root/main/openswan/openswan-libreswan-backport-949437-atodn.patch
blob: 524a75b20feb82b32fd9d6ac36713c0c5b5463f1 (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
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
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);