OLD | NEW |
1 /* This Source Code Form is subject to the terms of the Mozilla Public | 1 /* This Source Code Form is subject to the terms of the Mozilla Public |
2 * License, v. 2.0. If a copy of the MPL was not distributed with this | 2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
4 | 4 |
5 #include "secder.h" | 5 #include "secder.h" |
6 #include <limits.h> | 6 #include <limits.h> |
7 #include "secerr.h" | 7 #include "secerr.h" |
8 | 8 |
9 int | 9 int |
10 DER_LengthLength(PRUint32 len) | 10 DER_LengthLength(PRUint32 len) |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
172 } | 172 } |
173 | 173 |
174 /* | 174 /* |
175 ** Convert a der encoded *signed* integer into a machine integral value. | 175 ** Convert a der encoded *signed* integer into a machine integral value. |
176 ** If an underflow/overflow occurs, sets error code and returns min/max. | 176 ** If an underflow/overflow occurs, sets error code and returns min/max. |
177 */ | 177 */ |
178 long | 178 long |
179 DER_GetInteger(const SECItem *it) | 179 DER_GetInteger(const SECItem *it) |
180 { | 180 { |
181 long ival = 0; | 181 long ival = 0; |
182 unsigned len = it->len; | 182 PRBool negative = PR_FALSE; |
| 183 unsigned int len = it->len; |
| 184 unsigned int originalLength = len; |
183 unsigned char *cp = it->data; | 185 unsigned char *cp = it->data; |
184 unsigned long overflow = 0x1ffUL << (((sizeof(ival) - 1) * 8) - 1); | 186 unsigned long overflow = 0x1ffUL << (((sizeof(ival) - 1) * 8) - 1); |
185 unsigned long ofloinit; | 187 unsigned long mask = 1; |
186 | 188 |
187 PORT_Assert(len); | 189 PORT_Assert(len); |
188 if (!len) { | 190 if (!len) { |
189 PORT_SetError(SEC_ERROR_INPUT_LEN); | 191 PORT_SetError(SEC_ERROR_INPUT_LEN); |
190 return 0; | 192 return 0; |
191 } | 193 } |
192 | 194 |
193 if (*cp & 0x80) | 195 if (*cp & 0x80) { |
194 » ival = -1L; | 196 » negative = PR_TRUE; |
195 ofloinit = ival & overflow; | 197 » overflow <<= 1; |
| 198 } |
196 | 199 |
197 while (len) { | 200 while (len) { |
198 » if ((ival & overflow) != ofloinit) { | 201 » if ((ival & overflow) != 0) { |
199 PORT_SetError(SEC_ERROR_BAD_DER); | 202 PORT_SetError(SEC_ERROR_BAD_DER); |
200 » if (ival < 0) { | 203 » if (negative) { |
201 return LONG_MIN; | 204 return LONG_MIN; |
202 } | 205 } |
203 return LONG_MAX; | 206 return LONG_MAX; |
204 } | 207 } |
205 ival = ival << 8; | 208 ival = ival << 8; |
206 ival |= *cp++; | 209 ival |= *cp++; |
207 --len; | 210 --len; |
208 } | 211 } |
| 212 if (negative && ival && (overflow & ival) == 0) { |
| 213 mask <<= ((originalLength * 8) - 1); |
| 214 ival &= ~mask; |
| 215 ival -= mask; |
| 216 } |
209 return ival; | 217 return ival; |
210 } | 218 } |
211 | 219 |
212 /* | 220 /* |
213 ** Convert a der encoded *unsigned* integer into a machine integral value. | 221 ** Convert a der encoded *unsigned* integer into a machine integral value. |
214 ** If an overflow occurs, sets error code and returns max. | 222 ** If an overflow occurs, sets error code and returns max. |
215 */ | 223 */ |
216 unsigned long | 224 unsigned long |
217 DER_GetUInteger(SECItem *it) | 225 DER_GetUInteger(SECItem *it) |
218 { | 226 { |
(...skipping 18 matching lines...) Expand all Loading... |
237 if (ival & overflow) { | 245 if (ival & overflow) { |
238 PORT_SetError(SEC_ERROR_BAD_DER); | 246 PORT_SetError(SEC_ERROR_BAD_DER); |
239 return ULONG_MAX; | 247 return ULONG_MAX; |
240 } | 248 } |
241 ival = ival << 8; | 249 ival = ival << 8; |
242 ival |= *cp++; | 250 ival |= *cp++; |
243 --len; | 251 --len; |
244 } | 252 } |
245 return ival; | 253 return ival; |
246 } | 254 } |
OLD | NEW |