Skip to content

Fix too short ASN.1 value error on Xcode receipts with jsrsasign 11.1.2+#418

Open
adityasingh2400 wants to merge 1 commit into
apple:mainfrom
adityasingh2400:fix-xcode-receipt-asn1-jsrsasign-1112
Open

Fix too short ASN.1 value error on Xcode receipts with jsrsasign 11.1.2+#418
adityasingh2400 wants to merge 1 commit into
apple:mainfrom
adityasingh2400:fix-xcode-receipt-asn1-jsrsasign-1112

Conversation

@adityasingh2400
Copy link
Copy Markdown

Fixes #417.

A fresh install of the library resolves jsrsasign to 11.1.3 (the declared range is ^11.0.0), and on any version >= 11.1.2 ReceiptUtility.extractTransactionIdFromAppReceipt() throws Error: too short ASN.1 value when parsing Xcode generated app receipts. Production App Store receipts are unaffected because they use definite length encoding. The committed lockfile pins 11.1.1, so CI stays green while consumers who install today get the broken parse.

The root cause is a behavior change in jsrsasign. Xcode receipts use indefinite length encoding (30 80 ...), which jsrsasign does not support natively, so this method monkey-patches ASN1HEX.getVblen and ASN1HEX.getLblen to round the indefinite length up to the remaining bytes. In 11.1.2 a new bounds check was added to ASN1HEX.getChildIdx:

c = getVidx(e, k);
f = getVblen(e, k) * 2;
if (c + f > e.length) { throw new Error("too short ASN.1 value") }

getVidx returns the index of the value, which is the tag index plus the tag and length octets. The patched getVblen returned (s.length - idx) / 2, where idx is the tag index, so for an indefinite length node c + f equals getVidx + (s.length - idx), which is s.length plus the header length. That overshoots e.length by the header size and trips the new check. 11.1.1 did not have this check, which is why the regression only appears on 11.1.2 and later.

The fix measures the remaining length from the value index instead of the tag index: (s.length - ASN1HEX.getVidx(s, idx)) / 2. That makes c + f equal s.length exactly, so the bounds check passes and the rest of the traversal is unchanged. This is the semantically correct value: getVblen is meant to return the length of the value, which starts after the header.

Verified by running the existing receipt tests against jsrsasign 11.1.1, 11.1.2, and 11.1.3. Before the change the two Xcode receipt tests fail with too short ASN.1 value on 11.1.2 and 11.1.3 and pass on 11.1.1. After the change all of them extract the expected transaction id on every version, so the fix is correct without needing to pin the dependency. I also added a regression test that asserts parsing an indefinite length Xcode receipt does not throw and returns the expected id. The full suite is 166 passing on both 11.1.1 and 11.1.3, and tsc builds clean.

Measure the indefinite length value from the value index rather than the
tag index so the patched getVblen no longer overshoots the bounds check
that jsrsasign 11.1.2 added to getChildIdx.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ReceiptUtility.extractTransactionIdFromAppReceipt throws "too short ASN.1 value" on Xcode receipts with jsrsasign >= 11.1.2

1 participant