diff --git a/src/cryptoconditions/src/cryptoconditions.c b/src/cryptoconditions/src/cryptoconditions.c index 74949affc..f7acde1aa 100644 --- a/src/cryptoconditions/src/cryptoconditions.c +++ b/src/cryptoconditions/src/cryptoconditions.c @@ -117,14 +117,15 @@ uint32_t fromAsnSubtypes(const ConditionTypes_t types) { size_t cc_conditionBinary(const CC *cond, unsigned char *buf) { Condition_t *asn = calloc(1, sizeof(Condition_t)); - asnCondition(cond, asn); + bool r = asnCondition(cond, asn); + size_t out = 0; + if (!r) goto end; asn_enc_rval_t rc = der_encode_to_buffer(&asn_DEF_Condition, asn, buf, 1000); - if (rc.encoded == -1) { - fprintf(stderr, "CONDITION NOT ENCODED\n"); - return 0; - } + if (rc.encoded == -1) goto end; + out = rc.encoded; +end: ASN_STRUCT_FREE(asn_DEF_Condition, asn); - return rc.encoded; + return out; } @@ -140,17 +141,22 @@ size_t cc_fulfillmentBinary(const CC *cond, unsigned char *buf, size_t length) { } -void asnCondition(const CC *cond, Condition_t *asn) { +bool asnCondition(const CC *cond, Condition_t *asn) { asn->present = cc_isAnon(cond) ? cond->conditionType->asnType : cond->type->asnType; // This may look a little weird - we dont have a reference here to the correct // union choice for the condition type, so we just assign everything to the threshold // type. This works out nicely since the union choices have the same binary interface. + CompoundSha256Condition_t *choice = &asn->choice.thresholdSha256; choice->cost = cc_getCost(cond); choice->fingerprint.buf = cond->type->fingerprint(cond); + if (choice->fingerprint.buf == 0) { + return 0; + } choice->fingerprint.size = 32; choice->subtypes = asnSubtypes(cond->type->getSubtypes(cond)); + return 1; } diff --git a/src/cryptoconditions/src/internal.h b/src/cryptoconditions/src/internal.h index 790e28962..e2525cbe4 100644 --- a/src/cryptoconditions/src/internal.h +++ b/src/cryptoconditions/src/internal.h @@ -65,7 +65,7 @@ extern int CCTypeRegistryLength; */ uint32_t fromAsnSubtypes(ConditionTypes_t types); CC *mkAnon(const Condition_t *asnCond); -void asnCondition(const CC *cond, Condition_t *asn); +bool asnCondition(const CC *cond, Condition_t *asn); Condition_t *asnConditionNew(const CC *cond); Fulfillment_t *asnFulfillmentNew(const CC *cond); struct CC *fulfillmentToCC(Fulfillment_t *ffill); diff --git a/src/cryptoconditions/tests/test_failure_modes.py b/src/cryptoconditions/tests/test_failure_modes.py index 59b0b3f24..435e20c88 100644 --- a/src/cryptoconditions/tests/test_failure_modes.py +++ b/src/cryptoconditions/tests/test_failure_modes.py @@ -82,4 +82,25 @@ def test_malleability_checked(): assert not cc_rfb(b'\xa2\x13\xa0\x0f\xa0\x06\x80\x04abcd\xa0\x05\x80\x03abc\xa1\x00') +def test_large_threshold(): + conds = [{ + 'type': "secp256k1-sha-256", + "publicKey": "02D5D969305535AC29A77079C11D4F0DD40661CF96E04E974A5E8D7E374EE225AA" + }] + + for i in range(250): + conds.append({ + "type": "eval-sha-256", + "code": "VEVTVAE" + }) + + r = jsonRPC("encodeCondition", { + "type": "threshold-sha-256", + "subfulfillments": conds, + "threshold": 251 + }) + assert 'error' not in r, r + + + so.cc_conditionUri.restype = ctypes.c_char_p