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; |
