Skip to content

Commit 773c549

Browse files
committed
test(chainbase): cover TransactionCapsule PQ defensive branches
1 parent 5b21959 commit 773c549

1 file changed

Lines changed: 165 additions & 0 deletions

File tree

framework/src/test/java/org/tron/core/capsule/TransactionCapsuleTest.java

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,171 @@ public void transactionSizeComparisonByScheme() {
352352
Assert.assertTrue(trc20[1][2] < trc20[0][2]);
353353
}
354354

355+
@Test
356+
public void pqAuthSigWrongPublicKeyLengthRejected() throws Exception {
357+
dbManager.getDynamicPropertiesStore().saveAllowFnDsa512(1L);
358+
FNDSA kp = new FNDSA();
359+
putAccountWithPQPermission(PQ_OWNER_HEX, kp.getPublicKey(), PQScheme.FN_DSA_512);
360+
361+
Transaction tx = buildTransferTx(PQ_OWNER_HEX, 0);
362+
byte[] txid = Sha256Hash.of(true, tx.getRawData().toByteArray()).getBytes();
363+
byte[] sig = FNDSA.sign(kp.getPrivateKey(), txid);
364+
365+
// Truncate public key by one byte to force the length-mismatch branch.
366+
byte[] shortPub = new byte[FNDSA.PUBLIC_KEY_LENGTH - 1];
367+
System.arraycopy(kp.getPublicKey(), 0, shortPub, 0, shortPub.length);
368+
369+
Transaction signed = tx.toBuilder()
370+
.addPqAuthSig(PQAuthSig.newBuilder()
371+
.setScheme(PQScheme.FN_DSA_512)
372+
.setPublicKey(ByteString.copyFrom(shortPub))
373+
.setSignature(ByteString.copyFrom(sig))
374+
.build())
375+
.build();
376+
TransactionCapsule cap = new TransactionCapsule(signed);
377+
try {
378+
cap.validatePubSignature(dbManager.getAccountStore(),
379+
dbManager.getDynamicPropertiesStore());
380+
Assert.fail("wrong public key length must be rejected");
381+
} catch (ValidateSignatureException e) {
382+
Assert.assertTrue(e.getMessage().contains("public key or signature length mismatch"));
383+
}
384+
}
385+
386+
@Test
387+
public void pqAuthSigWrongSignatureLengthRejected() throws Exception {
388+
dbManager.getDynamicPropertiesStore().saveAllowFnDsa512(1L);
389+
FNDSA kp = new FNDSA();
390+
putAccountWithPQPermission(PQ_OWNER_HEX, kp.getPublicKey(), PQScheme.FN_DSA_512);
391+
392+
Transaction tx = buildTransferTx(PQ_OWNER_HEX, 0);
393+
394+
// Empty signature is not a valid FN-DSA-512 length, hits the same branch.
395+
Transaction signed = tx.toBuilder()
396+
.addPqAuthSig(PQAuthSig.newBuilder()
397+
.setScheme(PQScheme.FN_DSA_512)
398+
.setPublicKey(ByteString.copyFrom(kp.getPublicKey()))
399+
.setSignature(ByteString.EMPTY)
400+
.build())
401+
.build();
402+
TransactionCapsule cap = new TransactionCapsule(signed);
403+
try {
404+
cap.validatePubSignature(dbManager.getAccountStore(),
405+
dbManager.getDynamicPropertiesStore());
406+
Assert.fail("wrong signature length must be rejected");
407+
} catch (ValidateSignatureException e) {
408+
Assert.assertTrue(e.getMessage().contains("public key or signature length mismatch"));
409+
}
410+
}
411+
412+
@Test
413+
public void pqAuthSigUnsupportedSchemeRejected() throws Exception {
414+
dbManager.getDynamicPropertiesStore().saveAllowFnDsa512(1L);
415+
FNDSA kp = new FNDSA();
416+
putAccountWithPQPermission(PQ_OWNER_HEX, kp.getPublicKey(), PQScheme.FN_DSA_512);
417+
418+
Transaction tx = buildTransferTx(PQ_OWNER_HEX, 0);
419+
byte[] txid = Sha256Hash.of(true, tx.getRawData().toByteArray()).getBytes();
420+
byte[] sig = FNDSA.sign(kp.getPrivateKey(), txid);
421+
422+
// setSchemeValue(99) sets an unknown numeric tag; reading back yields
423+
// PQScheme.UNRECOGNIZED, which PQSchemeRegistry.contains() rejects.
424+
Transaction signed = tx.toBuilder()
425+
.addPqAuthSig(PQAuthSig.newBuilder()
426+
.setSchemeValue(99)
427+
.setPublicKey(ByteString.copyFrom(kp.getPublicKey()))
428+
.setSignature(ByteString.copyFrom(sig))
429+
.build())
430+
.build();
431+
TransactionCapsule cap = new TransactionCapsule(signed);
432+
try {
433+
cap.validatePubSignature(dbManager.getAccountStore(),
434+
dbManager.getDynamicPropertiesStore());
435+
Assert.fail("unsupported scheme must be rejected");
436+
} catch (ValidateSignatureException e) {
437+
Assert.assertTrue(e.getMessage().contains("unsupported pq scheme"));
438+
}
439+
}
440+
441+
@Test
442+
public void validatePubSignatureRejectsMissingSig() {
443+
Transaction tx = buildTransferTx(PQ_OWNER_HEX, 0);
444+
TransactionCapsule cap = new TransactionCapsule(tx);
445+
try {
446+
cap.validatePubSignature(dbManager.getAccountStore(),
447+
dbManager.getDynamicPropertiesStore());
448+
Assert.fail("transaction with no signatures must be rejected");
449+
} catch (ValidateSignatureException e) {
450+
Assert.assertTrue(e.getMessage().contains("miss sig"));
451+
}
452+
}
453+
454+
@Test
455+
public void validatePubSignatureRejectsMissingContract() throws Exception {
456+
dbManager.getDynamicPropertiesStore().saveAllowFnDsa512(1L);
457+
FNDSA kp = new FNDSA();
458+
byte[] sig = FNDSA.sign(kp.getPrivateKey(), new byte[32]);
459+
460+
// No contracts in raw_data, but a pq_auth_sig is attached so we get past
461+
// the "miss sig" guard and into the "miss contract" branch.
462+
Transaction tx = Transaction.newBuilder()
463+
.setRawData(raw.newBuilder().build())
464+
.addPqAuthSig(PQAuthSig.newBuilder()
465+
.setScheme(PQScheme.FN_DSA_512)
466+
.setPublicKey(ByteString.copyFrom(kp.getPublicKey()))
467+
.setSignature(ByteString.copyFrom(sig))
468+
.build())
469+
.build();
470+
TransactionCapsule cap = new TransactionCapsule(tx);
471+
try {
472+
cap.validatePubSignature(dbManager.getAccountStore(),
473+
dbManager.getDynamicPropertiesStore());
474+
Assert.fail("transaction with no contracts must be rejected");
475+
} catch (ValidateSignatureException e) {
476+
Assert.assertTrue(e.getMessage().contains("miss contract"));
477+
}
478+
}
479+
480+
@Test
481+
public void validatePubSignatureRejectsTooManySignatures() throws Exception {
482+
dbManager.getDynamicPropertiesStore().saveAllowFnDsa512(1L);
483+
int original = dbManager.getDynamicPropertiesStore().getTotalSignNum();
484+
try {
485+
dbManager.getDynamicPropertiesStore().saveTotalSignNum(1);
486+
FNDSA a = new FNDSA();
487+
FNDSA b = new FNDSA();
488+
putAccountWithPQPermission(PQ_OWNER_HEX, a.getPublicKey(), PQScheme.FN_DSA_512);
489+
490+
Transaction tx = buildTransferTx(PQ_OWNER_HEX, 0);
491+
byte[] txid = Sha256Hash.of(true, tx.getRawData().toByteArray()).getBytes();
492+
byte[] sigA = FNDSA.sign(a.getPrivateKey(), txid);
493+
byte[] sigB = FNDSA.sign(b.getPrivateKey(), txid);
494+
495+
Transaction signed = tx.toBuilder()
496+
.addPqAuthSig(PQAuthSig.newBuilder()
497+
.setScheme(PQScheme.FN_DSA_512)
498+
.setPublicKey(ByteString.copyFrom(a.getPublicKey()))
499+
.setSignature(ByteString.copyFrom(sigA))
500+
.build())
501+
.addPqAuthSig(PQAuthSig.newBuilder()
502+
.setScheme(PQScheme.FN_DSA_512)
503+
.setPublicKey(ByteString.copyFrom(b.getPublicKey()))
504+
.setSignature(ByteString.copyFrom(sigB))
505+
.build())
506+
.build();
507+
TransactionCapsule cap = new TransactionCapsule(signed);
508+
try {
509+
cap.validatePubSignature(dbManager.getAccountStore(),
510+
dbManager.getDynamicPropertiesStore());
511+
Assert.fail("more sigs than totalSignNum must be rejected");
512+
} catch (ValidateSignatureException e) {
513+
Assert.assertTrue(e.getMessage().contains("too many signatures"));
514+
}
515+
} finally {
516+
dbManager.getDynamicPropertiesStore().saveTotalSignNum(original);
517+
}
518+
}
519+
355520
@Test
356521
public void fnDsaPQAuthSigRejectedWhenNotActivated() throws Exception {
357522
dbManager.getDynamicPropertiesStore().saveAllowFnDsa512(0L);

0 commit comments

Comments
 (0)