Project

General

Profile

strongswan-5.0.0-5.5.2_asn1_choice.patch

Fabrice Barconnière, 05/17/2017 11:08 AM

Download (15.5 KB)

View differences:

src/libstrongswan/asn1/asn1_parser.c
1 1
/*
2 2
 * Copyright (C) 2006 Martin Will
3
 * Copyright (C) 2000-2008 Andreas Steffen
4
 *
5
 * Hochschule fuer Technik Rapperswil
3
 * Copyright (C) 2000-2017 Andreas Steffen
4
 * HSR Hochschule fuer Technik Rapperswil
6 5
 *
7 6
 * This program is free software; you can redistribute it and/or modify it
8 7
 * under the terms of the GNU General Public License as published by the
......
76 75
	 * Current parsing pointer for each level
77 76
	 */
78 77
	chunk_t blobs[ASN1_MAX_LEVEL + 2];
78

  
79
	/**
80
	 * Parsing a CHOICE on the current level ?
81
	 */
82
	bool choice[ASN1_MAX_LEVEL + 2];
83

  
79 84
};
80 85

  
81 86
METHOD(asn1_parser_t, iterate, bool,
82 87
	private_asn1_parser_t *this, int *objectID, chunk_t *object)
83 88
{
84
	chunk_t *blob, *blob1;
89
	chunk_t *blob, *blob1, blob_ori;
85 90
	u_char *start_ptr;
86 91
	u_int level;
87 92
	asn1Object_t obj;
......
97 102
		return FALSE;
98 103
	}
99 104

  
100
	if (obj.flags & ASN1_END)  /* end of loop or option found */
105
	if (obj.flags & ASN1_END)  /* end of loop or choice or option found */
101 106
	{
102 107
		if (this->loopAddr[obj.level] && this->blobs[obj.level+1].len > 0)
103 108
		{
......
106 111
		}
107 112
		else
108 113
		{
109
			this->loopAddr[obj.level] = 0;		 /* exit loop or option*/
114
			this->loopAddr[obj.level] = 0;		 /* exit loop */
115

  
116
			if (obj.flags & ASN1_CHOICE) /* end of choices */
117
			{
118
				if (this->choice[obj.level+1])
119
				{
120
					DBG1(DBG_ASN, "L%d - %s:  incorrect choice encoding",
121
						this->level0 + obj.level, obj.name);
122
					this->success = FALSE;
123
					goto end;
124
				}
125
			}
126

  
127
			if (obj.flags & ASN1_CH) /* end of choice */
128
			{
129
				/* parsed a valid choice */
130
				this->choice[obj.level] = FALSE;
131

  
132
				/* advance to end of choices */
133
				do
134
				{
135
					this->line++;
136
				}
137
				while (!((this->objects[this->line].flags & ASN1_END) &&
138
						 (this->objects[this->line].flags & ASN1_CHOICE) &&
139
						 (this->objects[this->line].level == obj.level-1)));
140
				this->line--;
141
			}
142

  
110 143
			goto end;
111 144
		}
112 145
	}
113 146

  
114 147
	level = this->level0 + obj.level;
115 148
	blob = this->blobs + obj.level;
149
	blob_ori = *blob;
116 150
	blob1 = blob + 1;
117 151
	start_ptr = blob->ptr;
118 152

  
......
129 163
	}
130 164

  
131 165
	/* handle ASN.1 options */
132

  
133 166
	if ((obj.flags & ASN1_OPT)
134 167
			&& (blob->len == 0 || *start_ptr != obj.type))
135 168
	{
......
144 177
	}
145 178

  
146 179
	/* an ASN.1 object must possess at least a tag and length field */
147

  
148 180
	if (blob->len < 2)
149 181
	{
150 182
		DBG1(DBG_ASN, "L%d - %s:  ASN.1 object smaller than 2 octets",
......
167 199
	blob->ptr += blob1->len;
168 200
	blob->len -= blob1->len;
169 201

  
170
	/* return raw ASN.1 object without prior type checking */
202
	/* handle ASN.1 choice without explicit context encoding */
203
	if ((obj.flags & ASN1_CHOICE) && obj.type == ASN1_EOC)
204
	{
205
		DBG2(DBG_ASN, "L%d - %s:", level, obj.name);
206
		this->choice[obj.level+1] = TRUE;
207
		*blob1 = blob_ori;
208
		goto end;
209
	}
171 210

  
211
	/* return raw ASN.1 object without prior type checking */
172 212
	if (obj.flags & ASN1_RAW)
173 213
	{
174 214
		DBG2(DBG_ASN, "L%d - %s:", level, obj.name);
......
209 249
		}
210 250
	}
211 251

  
252
	/* In case of a "CHOICE" start to scan for exactly one valid choice */
253
	if (obj.flags & ASN1_CHOICE)
254
	{
255
		if (blob1->len == 0)
256
		{
257
			DBG1(DBG_ASN, "L%d - %s:  contains no choice", level, obj.name);
258
			this->success = FALSE;
259
			goto end;
260
		}
261
		this->choice[obj.level+1] = TRUE;
262
	}
263

  
212 264
	if (obj.flags & ASN1_OBJ)
213 265
	{
214 266
		object->ptr = start_ptr;
src/libstrongswan/asn1/asn1_parser.h
1 1
/*
2 2
 * Copyright (C) 2006 Martin Will
3
 * Copyright (C) 2000-2008 Andreas Steffen
4
 *
5
 * Hochschule fuer Technik Rapperswil
3
 * Copyright (C) 2000-2017 Andreas Steffen
4
 * HSR Hochschule fuer Technik Rapperswil
6 5
 *
7 6
 * This program is free software; you can redistribute it and/or modify it
8 7
 * under the terms of the GNU General Public License as published by the
......
32 31
/**
33 32
 * Definition of ASN.1 flags
34 33
 */
35
#define ASN1_NONE	0x00
36
#define ASN1_DEF	0x01
37
#define ASN1_OPT	0x02
38
#define ASN1_LOOP	0x04
39
#define ASN1_END	0x08
40
#define ASN1_OBJ	0x10
41
#define ASN1_BODY	0x20
42
#define ASN1_RAW	0x40
43
#define ASN1_EXIT	0x80
34
#define ASN1_NONE    0x0000
35
#define ASN1_DEF     0x0001
36
#define ASN1_OPT     0x0002
37
#define ASN1_LOOP    0x0004
38
#define ASN1_CHOICE  0x0008
39
#define ASN1_CH      0x0010
40
#define ASN1_END     0x0020
41
#define ASN1_OBJ     0x0040
42
#define ASN1_BODY    0x0080
43
#define ASN1_RAW     0x0100
44
#define ASN1_EXIT    0x0200
44 45

  
45 46
typedef struct asn1Object_t asn1Object_t;
46 47

  
......
51 52
	u_int level;
52 53
	const u_char *name;
53 54
	asn1_t type;
54
	u_char flags;
55
	uint16_t flags;
55 56
};
56 57

  
57 58
typedef struct asn1_parser_t asn1_parser_t;
src/libstrongswan/plugins/x509/x509_cert.c
2 2
 * Copyright (C) 2000 Andreas Hess, Patric Lichtsteiner, Roger Wegmann
3 3
 * Copyright (C) 2001 Marco Bertossa, Andreas Schleiss
4 4
 * Copyright (C) 2002 Mario Strasser
5
 * Copyright (C) 2000-2006 Andreas Steffen
5
 * Copyright (C) 2000-2017 Andreas Steffen
6 6
 * Copyright (C) 2006-2009 Martin Willi
7 7
 * Copyright (C) 2008 Tobias Brunner
8
 * Hochschule fuer Technik Rapperswil
8
 * HSR Hochschule fuer Technik Rapperswil
9 9
 *
10 10
 * This program is free software; you can redistribute it and/or modify it
11 11
 * under the terms of the GNU General Public License as published by the
......
789 789
 * ASN.1 definition of crlDistributionPoints
790 790
 */
791 791
static const asn1Object_t crlDistributionPointsObjects[] = {
792
	{ 0, "crlDistributionPoints",	ASN1_SEQUENCE,		ASN1_LOOP			}, /*  0 */
793
	{ 1,   "DistributionPoint",		ASN1_SEQUENCE,		ASN1_NONE			}, /*  1 */
794
	{ 2,     "distributionPoint",	ASN1_CONTEXT_C_0,	ASN1_OPT|ASN1_LOOP	}, /*  2 */
795
	{ 3,       "fullName",			ASN1_CONTEXT_C_0,	ASN1_OPT|ASN1_OBJ	}, /*  3 */
796
	{ 3,       "end choice",		ASN1_EOC,			ASN1_END			}, /*  4 */
797
	{ 3,       "nameRelToCRLIssuer",ASN1_CONTEXT_C_1,	ASN1_OPT|ASN1_BODY	}, /*  5 */
798
	{ 3,       "end choice",		ASN1_EOC,			ASN1_END			}, /*  6 */
799
	{ 2,     "end opt",				ASN1_EOC,			ASN1_END			}, /*  7 */
800
	{ 2,     "reasons",				ASN1_CONTEXT_C_1,	ASN1_OPT|ASN1_BODY	}, /*  8 */
801
	{ 2,     "end opt",				ASN1_EOC,			ASN1_END			}, /*  9 */
802
	{ 2,     "crlIssuer",			ASN1_CONTEXT_C_2,	ASN1_OPT|ASN1_OBJ	}, /* 10 */
803
	{ 2,     "end opt",				ASN1_EOC,			ASN1_END			}, /* 11 */
804
	{ 0, "end loop",				ASN1_EOC,			ASN1_END			}, /* 12 */
805
	{ 0, "exit",					ASN1_EOC,			ASN1_EXIT			}
792
	{ 0, "crlDistributionPoints",   ASN1_SEQUENCE,    ASN1_LOOP            }, /*  0 */
793
	{ 1,   "DistributionPoint",     ASN1_SEQUENCE,    ASN1_NONE            }, /*  1 */
794
	{ 2,     "distributionPoint",   ASN1_CONTEXT_C_0, ASN1_OPT|ASN1_CHOICE }, /*  2 */
795
	{ 3,       "fullName",          ASN1_CONTEXT_C_0, ASN1_OPT|ASN1_OBJ    }, /*  3 */
796
	{ 3,       "end choice",        ASN1_EOC,         ASN1_END|ASN1_CH     }, /*  4 */
797
	{ 3,       "nameRelToCRLIssuer",ASN1_CONTEXT_C_1, ASN1_OPT|ASN1_BODY   }, /*  5 */
798
	{ 3,       "end choice",        ASN1_EOC,         ASN1_END|ASN1_CH     }, /*  6 */
799
	{ 2,     "end opt/choices",     ASN1_EOC,         ASN1_END|ASN1_CHOICE }, /*  7 */
800
	{ 2,     "reasons",             ASN1_CONTEXT_C_1, ASN1_OPT|ASN1_BODY   }, /*  8 */
801
	{ 2,     "end opt",             ASN1_EOC,         ASN1_END             }, /*  9 */
802
	{ 2,     "crlIssuer",           ASN1_CONTEXT_C_2, ASN1_OPT|ASN1_OBJ    }, /* 10 */
803
	{ 2,     "end opt",             ASN1_EOC,         ASN1_END             }, /* 11 */
804
	{ 0, "end loop",                ASN1_EOC,         ASN1_END             }, /* 12 */
805
	{ 0, "exit",                    ASN1_EOC,         ASN1_EXIT            }
806 806
};
807 807
#define CRL_DIST_POINTS				 1
808 808
#define CRL_DIST_POINTS_FULLNAME	 3
......
910 910
 * ASN.1 definition of nameConstraints
911 911
 */
912 912
static const asn1Object_t nameConstraintsObjects[] = {
913
	{ 0, "nameConstraints",			ASN1_SEQUENCE,		ASN1_LOOP			}, /*  0 */
913
	{ 0, "nameConstraints",			ASN1_SEQUENCE,		ASN1_NONE			}, /*  0 */
914 914
	{ 1,   "permittedSubtrees",		ASN1_CONTEXT_C_0,	ASN1_OPT|ASN1_LOOP	}, /*  1 */
915 915
	{ 2,     "generalSubtree",		ASN1_SEQUENCE,		ASN1_BODY			}, /*  2 */
916 916
	{ 1,   "end loop",				ASN1_EOC,			ASN1_END			}, /*  3 */
917 917
	{ 1,   "excludedSubtrees",		ASN1_CONTEXT_C_1,	ASN1_OPT|ASN1_LOOP	}, /*  4 */
918 918
	{ 2,     "generalSubtree",		ASN1_SEQUENCE,		ASN1_BODY			}, /*  5 */
919 919
	{ 1,   "end loop",				ASN1_EOC,			ASN1_END			}, /*  6 */
920
	{ 0, "end loop",				ASN1_EOC,			ASN1_END			}, /*  7 */
921 920
	{ 0, "exit",					ASN1_EOC,			ASN1_EXIT			}
922 921
};
923 922
#define NAME_CONSTRAINT_PERMITTED 2
......
974 973
 * ASN.1 definition of a certificatePolicies extension
975 974
 */
976 975
static const asn1Object_t certificatePoliciesObject[] = {
977
	{ 0, "certificatePolicies",		ASN1_SEQUENCE,	ASN1_LOOP			}, /*  0 */
978
	{ 1,   "policyInformation",		ASN1_SEQUENCE,	ASN1_NONE			}, /*  1 */
979
	{ 2,     "policyId",			ASN1_OID,		ASN1_BODY			}, /*  2 */
980
	{ 2,     "qualifiers",			ASN1_SEQUENCE,	ASN1_OPT|ASN1_LOOP	}, /*  3 */
981
	{ 3,       "qualifierInfo",		ASN1_SEQUENCE,	ASN1_NONE			}, /*  4 */
982
	{ 4,         "qualifierId",		ASN1_OID,		ASN1_BODY			}, /*  5 */
983
	{ 4,         "cPSuri",			ASN1_IA5STRING,	ASN1_OPT|ASN1_BODY	}, /*  6 */
984
	{ 4,         "end choice",		ASN1_EOC,		ASN1_END			}, /*  7 */
985
	{ 4,         "userNotice",		ASN1_SEQUENCE,	ASN1_OPT|ASN1_BODY	}, /*  8 */
986
	{ 5,           "explicitText",	ASN1_EOC,		ASN1_RAW			}, /*  9 */
987
	{ 4,         "end choice",		ASN1_EOC,		ASN1_END			}, /* 10 */
988
	{ 2,      "end opt/loop",		ASN1_EOC,		ASN1_END			}, /* 12 */
989
	{ 0, "end loop",				ASN1_EOC,		ASN1_END			}, /* 13 */
990
	{ 0, "exit",					ASN1_EOC,		ASN1_EXIT			}
976
	{ 0, "certificatePolicies",      ASN1_SEQUENCE,  ASN1_LOOP            }, /*  0 */
977
	{ 1,   "policyInformation",      ASN1_SEQUENCE,  ASN1_NONE            }, /*  1 */
978
	{ 2,     "policyId",             ASN1_OID,       ASN1_BODY            }, /*  2 */
979
	{ 2,     "qualifiers",           ASN1_SEQUENCE,  ASN1_OPT|ASN1_LOOP   }, /*  3 */
980
	{ 3,       "qualifierInfo",      ASN1_SEQUENCE,  ASN1_NONE            }, /*  4 */
981
	{ 4,         "qualifierId",      ASN1_OID,       ASN1_BODY            }, /*  5 */
982
	{ 4,         "qualifier",        ASN1_EOC,       ASN1_CHOICE          }, /*  6 */
983
	{ 5,           "cPSuri",         ASN1_IA5STRING, ASN1_OPT|ASN1_BODY   }, /*  7 */
984
	{ 5,           "end choice",     ASN1_EOC,       ASN1_END|ASN1_CH     }, /*  8 */
985
	{ 5,           "userNotice",     ASN1_SEQUENCE,  ASN1_OPT|ASN1_BODY   }, /*  9 */
986
	{ 6,             "explicitText", ASN1_EOC,       ASN1_RAW             }, /* 10 */
987
	{ 5,           "end choice",     ASN1_EOC,       ASN1_END|ASN1_CH     }, /* 11 */
988
	{ 4,         "end choices",      ASN1_EOC,       ASN1_END|ASN1_CHOICE }, /* 12 */
989
	{ 2,     "end opt/loop",         ASN1_EOC,       ASN1_END             }, /* 13 */
990
	{ 0, "end loop",                 ASN1_EOC,       ASN1_END             }, /* 14 */
991
	{ 0, "exit",                     ASN1_EOC,       ASN1_EXIT            }
991 992
};
992
#define CERT_POLICY_ID				2
993
#define CERT_POLICY_QUALIFIER_ID	5
994
#define CERT_POLICY_CPS_URI			6
995
#define CERT_POLICY_EXPLICIT_TEXT	9
993
#define CERT_POLICY_ID              2
994
#define CERT_POLICY_QUALIFIER_ID    5
995
#define CERT_POLICY_CPS_URI         7
996
#define CERT_POLICY_EXPLICIT_TEXT  10
996 997

  
997 998
/**
998 999
 * Parse certificatePolicies
......
1157 1158
 * ASN.1 definition of ipAddrBlocks according to RFC 3779
1158 1159
 */
1159 1160
static const asn1Object_t ipAddrBlocksObjects[] = {
1160
	{ 0, "ipAddrBlocks",			ASN1_SEQUENCE,		ASN1_LOOP			}, /*  0 */
1161
	{ 1,   "ipAddressFamily",		ASN1_SEQUENCE,		ASN1_NONE			}, /*  1 */
1162
	{ 2,     "addressFamily",		ASN1_OCTET_STRING,	ASN1_BODY			}, /*  2 */
1163
	{ 2,     "inherit",				ASN1_NULL,			ASN1_OPT|ASN1_NONE	}, /*  3 */
1164
	{ 2,     "end choice",			ASN1_EOC,			ASN1_END			}, /*  4 */
1165
	{ 2,     "addressesOrRanges",	ASN1_SEQUENCE,		ASN1_OPT|ASN1_LOOP	}, /*  5 */
1166
	{ 3,       "addressPrefix",		ASN1_BIT_STRING,	ASN1_OPT|ASN1_BODY  }, /*  6 */
1167
	{ 3,       "end choice",		ASN1_EOC,			ASN1_END			}, /*  7 */
1168
	{ 3,       "addressRange",		ASN1_SEQUENCE,		ASN1_OPT|ASN1_NONE	}, /*  8 */
1169
	{ 4,         "min",				ASN1_BIT_STRING,	ASN1_BODY			}, /*  9 */
1170
	{ 4,         "max",				ASN1_BIT_STRING,	ASN1_BODY			}, /* 10 */
1171
	{ 3,       "end choice",		ASN1_EOC,			ASN1_END			}, /* 11 */
1172
	{ 2,     "end opt/loop",		ASN1_EOC,			ASN1_END			}, /* 12 */
1173
	{ 0, "end loop",				ASN1_EOC,			ASN1_END			}, /* 13 */
1174
	{ 0, "exit",					ASN1_EOC,			ASN1_EXIT			}
1161
	{ 0, "ipAddrBlocks",            ASN1_SEQUENCE,     ASN1_LOOP            }, /*  0 */
1162
	{ 1,   "ipAddressFamily",       ASN1_SEQUENCE,     ASN1_NONE            }, /*  1 */
1163
	{ 2,     "addressFamily",       ASN1_OCTET_STRING, ASN1_BODY            }, /*  2 */
1164
	{ 2,     "ipAddressChoice",     ASN1_EOC,          ASN1_CHOICE          }, /*  3 */
1165
	{ 3,       "inherit",           ASN1_NULL,         ASN1_OPT             }, /*  4 */
1166
	{ 3,       "end choice",        ASN1_EOC,          ASN1_END|ASN1_CH     }, /*  5 */
1167
	{ 3,       "addressesOrRanges", ASN1_SEQUENCE,     ASN1_OPT|ASN1_LOOP   }, /*  6 */
1168
	{ 4,         "addressOrRange",  ASN1_EOC,          ASN1_CHOICE          }, /*  7 */
1169
	{ 5,           "addressPrefix", ASN1_BIT_STRING,   ASN1_OPT|ASN1_BODY   }, /*  8 */
1170
	{ 5,           "end choice",    ASN1_EOC,          ASN1_END|ASN1_CH     }, /*  9 */
1171
	{ 5,           "addressRange",  ASN1_SEQUENCE,     ASN1_OPT             }, /* 10 */
1172
	{ 6,             "min",         ASN1_BIT_STRING,   ASN1_BODY            }, /* 11 */
1173
	{ 6,             "max",         ASN1_BIT_STRING,   ASN1_BODY            }, /* 12 */
1174
	{ 5,           "end choice",    ASN1_EOC,          ASN1_END|ASN1_CH     }, /* 13 */
1175
	{ 4,         "end choices",     ASN1_EOC,          ASN1_END|ASN1_CHOICE }, /* 14 */
1176
	{ 3,       "end loop/choice",   ASN1_EOC,          ASN1_END|ASN1_CH     }, /* 15 */
1177
	{ 2,     "end choices",         ASN1_EOC,          ASN1_END|ASN1_CHOICE }, /* 16 */
1178
	{ 0, "end loop",                ASN1_EOC,          ASN1_END             }, /* 17 */
1179
	{ 0, "exit",                    ASN1_EOC,          ASN1_EXIT            }
1175 1180
};
1176 1181
#define IP_ADDR_BLOCKS_FAMILY       2
1177
#define IP_ADDR_BLOCKS_INHERIT      3
1178
#define IP_ADDR_BLOCKS_PREFIX       6
1179
#define IP_ADDR_BLOCKS_MIN          9
1180
#define IP_ADDR_BLOCKS_MAX         10
1182
#define IP_ADDR_BLOCKS_INHERIT      4
1183
#define IP_ADDR_BLOCKS_PREFIX       8
1184
#define IP_ADDR_BLOCKS_MIN         11
1185
#define IP_ADDR_BLOCKS_MAX         12
1181 1186

  
1182 1187
static bool check_address_object(ts_type_t ts_type, chunk_t object)
1183 1188
{
1184
-