diff options
Diffstat (limited to 'lib/asn1_decoder.c')
-rw-r--r-- | lib/asn1_decoder.c | 49 |
1 files changed, 28 insertions, 21 deletions
diff --git a/lib/asn1_decoder.c b/lib/asn1_decoder.c index 1ef0cec38d78..dc14beae2c9a 100644 --- a/lib/asn1_decoder.c +++ b/lib/asn1_decoder.c | |||
@@ -313,42 +313,47 @@ next_op: | |||
313 | 313 | ||
314 | /* Decide how to handle the operation */ | 314 | /* Decide how to handle the operation */ |
315 | switch (op) { | 315 | switch (op) { |
316 | case ASN1_OP_MATCH_ANY_ACT: | ||
317 | case ASN1_OP_MATCH_ANY_ACT_OR_SKIP: | ||
318 | case ASN1_OP_COND_MATCH_ANY_ACT: | ||
319 | case ASN1_OP_COND_MATCH_ANY_ACT_OR_SKIP: | ||
320 | ret = actions[machine[pc + 1]](context, hdr, tag, data + dp, len); | ||
321 | if (ret < 0) | ||
322 | return ret; | ||
323 | goto skip_data; | ||
324 | |||
325 | case ASN1_OP_MATCH_ACT: | ||
326 | case ASN1_OP_MATCH_ACT_OR_SKIP: | ||
327 | case ASN1_OP_COND_MATCH_ACT_OR_SKIP: | ||
328 | ret = actions[machine[pc + 2]](context, hdr, tag, data + dp, len); | ||
329 | if (ret < 0) | ||
330 | return ret; | ||
331 | goto skip_data; | ||
332 | |||
333 | case ASN1_OP_MATCH: | 316 | case ASN1_OP_MATCH: |
334 | case ASN1_OP_MATCH_OR_SKIP: | 317 | case ASN1_OP_MATCH_OR_SKIP: |
318 | case ASN1_OP_MATCH_ACT: | ||
319 | case ASN1_OP_MATCH_ACT_OR_SKIP: | ||
335 | case ASN1_OP_MATCH_ANY: | 320 | case ASN1_OP_MATCH_ANY: |
336 | case ASN1_OP_MATCH_ANY_OR_SKIP: | 321 | case ASN1_OP_MATCH_ANY_OR_SKIP: |
322 | case ASN1_OP_MATCH_ANY_ACT: | ||
323 | case ASN1_OP_MATCH_ANY_ACT_OR_SKIP: | ||
337 | case ASN1_OP_COND_MATCH_OR_SKIP: | 324 | case ASN1_OP_COND_MATCH_OR_SKIP: |
325 | case ASN1_OP_COND_MATCH_ACT_OR_SKIP: | ||
338 | case ASN1_OP_COND_MATCH_ANY: | 326 | case ASN1_OP_COND_MATCH_ANY: |
339 | case ASN1_OP_COND_MATCH_ANY_OR_SKIP: | 327 | case ASN1_OP_COND_MATCH_ANY_OR_SKIP: |
340 | skip_data: | 328 | case ASN1_OP_COND_MATCH_ANY_ACT: |
329 | case ASN1_OP_COND_MATCH_ANY_ACT_OR_SKIP: | ||
330 | |||
341 | if (!(flags & FLAG_CONS)) { | 331 | if (!(flags & FLAG_CONS)) { |
342 | if (flags & FLAG_INDEFINITE_LENGTH) { | 332 | if (flags & FLAG_INDEFINITE_LENGTH) { |
333 | size_t tmp = dp; | ||
334 | |||
343 | ret = asn1_find_indefinite_length( | 335 | ret = asn1_find_indefinite_length( |
344 | data, datalen, &dp, &len, &errmsg); | 336 | data, datalen, &tmp, &len, &errmsg); |
345 | if (ret < 0) | 337 | if (ret < 0) |
346 | goto error; | 338 | goto error; |
347 | } else { | ||
348 | dp += len; | ||
349 | } | 339 | } |
350 | pr_debug("- LEAF: %zu\n", len); | 340 | pr_debug("- LEAF: %zu\n", len); |
351 | } | 341 | } |
342 | |||
343 | if (op & ASN1_OP_MATCH__ACT) { | ||
344 | unsigned char act; | ||
345 | |||
346 | if (op & ASN1_OP_MATCH__ANY) | ||
347 | act = machine[pc + 1]; | ||
348 | else | ||
349 | act = machine[pc + 2]; | ||
350 | ret = actions[act](context, hdr, tag, data + dp, len); | ||
351 | if (ret < 0) | ||
352 | return ret; | ||
353 | } | ||
354 | |||
355 | if (!(flags & FLAG_CONS)) | ||
356 | dp += len; | ||
352 | pc += asn1_op_lengths[op]; | 357 | pc += asn1_op_lengths[op]; |
353 | goto next_op; | 358 | goto next_op; |
354 | 359 | ||
@@ -434,6 +439,8 @@ next_op: | |||
434 | else | 439 | else |
435 | act = machine[pc + 1]; | 440 | act = machine[pc + 1]; |
436 | ret = actions[act](context, hdr, 0, data + tdp, len); | 441 | ret = actions[act](context, hdr, 0, data + tdp, len); |
442 | if (ret < 0) | ||
443 | return ret; | ||
437 | } | 444 | } |
438 | pc += asn1_op_lengths[op]; | 445 | pc += asn1_op_lengths[op]; |
439 | goto next_op; | 446 | goto next_op; |