From d701bab7f6238a5cda4e3410e45dfe745889560c Mon Sep 17 00:00:00 2001 From: Mark Beamer Jr Date: Sat, 4 May 2019 00:00:23 -0400 Subject: [PATCH] Fixed claim signing after changes in https://github.com/lbryio/lbry/commit/90bef98bc3e814f412943a6ad2be9cc4a974ae41 --- claim/claim.go | 4 +++- claim/serialization.go | 13 ++++++------- claim/sign_test.go | 6 +++--- claim/validator.go | 22 ++++++++++++++-------- claim/validator_test.go | 39 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 65 insertions(+), 19 deletions(-) diff --git a/claim/claim.go b/claim/claim.go index 13f294f..f663cc4 100644 --- a/claim/claim.go +++ b/claim/claim.go @@ -31,6 +31,7 @@ type ClaimHelper struct { ClaimID []byte Version version Signature []byte + Payload []byte } const migrationErrorMessage = "migration from v1 to v2 protobuf failed with: " @@ -143,6 +144,7 @@ func (c *ClaimHelper) LoadFromBytes(raw_claim []byte, blockchainName string) err ClaimID: claimID, Version: version, Signature: signature, + Payload: pbPayload, } err = c.ValidateAddresses(blockchainName) @@ -166,7 +168,7 @@ func (c *ClaimHelper) LoadFromHexString(claim_hex string, blockchainName string) } func DecodeClaimProtoBytes(serialized []byte, blockchainName string) (*ClaimHelper, error) { - claim := &ClaimHelper{&pb.Claim{}, nil, nil, NoSig, nil} + claim := &ClaimHelper{&pb.Claim{}, nil, nil, NoSig, nil, nil} err := claim.LoadFromBytes(serialized, blockchainName) if err != nil { return nil, err diff --git a/claim/serialization.go b/claim/serialization.go index 8922d51..43d38d6 100644 --- a/claim/serialization.go +++ b/claim/serialization.go @@ -25,14 +25,13 @@ func (c *ClaimHelper) serialized() ([]byte, error) { func (c *ClaimHelper) getProtobuf() *pb.Claim { claim := &pb.Claim{ - Title: c.Title, - Description: c.Description, - Thumbnail: c.Thumbnail, - Tags: c.Tags, - Languages: c.Languages, - Locations: c.Locations, + Title: c.GetTitle(), + Description: c.GetDescription(), + Thumbnail: c.GetThumbnail(), + Tags: c.GetTags(), + Languages: c.GetLanguages(), + Locations: c.GetLocations(), } - return c.Claim if c.GetChannel() != nil { claim.Type = &pb.Claim_Channel{Channel: c.GetChannel()} } else if c.GetStream() != nil { diff --git a/claim/sign_test.go b/claim/sign_test.go index 314179c..e813f07 100644 --- a/claim/sign_test.go +++ b/claim/sign_test.go @@ -14,7 +14,7 @@ func TestSign(t *testing.T) { t.Error(err) return } - channel := &ClaimHelper{newChannelClaim(), nil, nil, NoSig, nil} + channel := &ClaimHelper{newChannelClaim(), nil, nil, NoSig, nil, nil} pubkeyBytes, err := PublicKeyToDER(privateKey.PubKey()) if err != nil { t.Error(err) @@ -29,7 +29,7 @@ func TestSign(t *testing.T) { return } - claim := &ClaimHelper{newStreamClaim(), nil, reverseBytes(claimIDHexBytes), WithSig, nil} + claim := &ClaimHelper{newStreamClaim(), nil, reverseBytes(claimIDHexBytes), WithSig, nil, nil} claim.Claim.Title = "Test title" claim.Claim.Description = "Test description" sig, err := Sign(*privateKey, *channel, *claim, txid) @@ -104,7 +104,7 @@ func TestSignWithV1Channel(t *testing.T) { return } - claim := &ClaimHelper{newStreamClaim(), nil, reverseBytes(claimIDHexBytes), WithSig, nil} + claim := &ClaimHelper{newStreamClaim(), nil, reverseBytes(claimIDHexBytes), WithSig, nil, nil} claim.Claim.Title = "Test title" claim.Claim.Description = "Test description" sig, err := Sign(*privateKey, *channel, *claim, txid) diff --git a/claim/validator.go b/claim/validator.go index 4edac28..4c243af 100644 --- a/claim/validator.go +++ b/claim/validator.go @@ -5,6 +5,7 @@ import ( "crypto/sha256" "crypto/x509/pkix" "encoding/asn1" + "encoding/binary" "encoding/hex" "math/big" @@ -57,13 +58,13 @@ func (c *ClaimHelper) ValidateClaimSignature(certificate *ClaimHelper, k string, return c.validateClaimSignature(certificate, k, certificateId, blockchainName) } -func (c *ClaimHelper) validateClaimSignature(certificate *ClaimHelper, firstInputTxID, certificateId string, blockchainName string) (bool, error) { +func (c *ClaimHelper) validateClaimSignature(certificate *ClaimHelper, firstInputTxHash, certificateId string, blockchainName string) (bool, error) { certificateIdSlice, err := hex.DecodeString(certificateId) if err != nil { return false, errors.Err(err) } certificateIdSlice = reverseBytes(certificateIdSlice) - firstInputTxIDBytes, err := hex.DecodeString(firstInputTxID) + firstInputTxIDBytes, err := hex.DecodeString(firstInputTxHash) if err != nil { return false, errors.Err(err) } @@ -77,12 +78,7 @@ func (c *ClaimHelper) validateClaimSignature(certificate *ClaimHelper, firstInpu signatureBytes[i] = b } - serialized, err := c.serialized() - if err != nil { - return false, errors.Err("serialization error") - } - - claimDigest := getClaimSignatureDigest(firstInputTxIDBytes, certificateIdSlice, serialized) + claimDigest := getClaimSignatureDigest(firstInputTxIDBytes, certificateIdSlice, c.Payload) return c.VerifyDigest(certificate, signatureBytes, claimDigest), nil } @@ -120,3 +116,13 @@ func (c *ClaimHelper) validateV1ClaimSignature(certificate *ClaimHelper, claimAd claimDigest := getClaimSignatureDigest(claimAddress[:], serializedNoSig, certificateIdSlice) return c.VerifyDigest(certificate, signatureBytes, claimDigest), nil } + +func GetOutpointHash(txid string, vout uint32) (string, error) { + txidBytes, err := hex.DecodeString(txid) + if err != nil { + return "", errors.Err(err) + } + var voutBytes = make([]byte, 4) + binary.LittleEndian.PutUint32(voutBytes, vout) + return hex.EncodeToString(append(reverseBytes(txidBytes), voutBytes...)), nil +} diff --git a/claim/validator_test.go b/claim/validator_test.go index eca3ba6..ef88a4d 100644 --- a/claim/validator_test.go +++ b/claim/validator_test.go @@ -2,6 +2,8 @@ package claim import ( "testing" + + "gotest.tools/assert" ) func TestV1ValidateClaimSignature(t *testing.T) { @@ -53,3 +55,40 @@ func TestV1FailToValidateClaimSignature(t *testing.T) { t.Error("failed to validate signature:", result) } } + +func TestV2ValidateClaimSignature(t *testing.T) { + cert_claim_hex := "00125a0a583056301006072a8648ce3d020106052b8104000a034200045a0343c155302280da01ae0001b7295241eb03c42a837acf92ccb9680892f7db50fd1d3c14b28bb594e304f05fc4ae7c1f222a85d1d1a3461b3cfb9906f66cb5" + signed_claim_hex := "015cb78e424a34fbf79b67f9107430427aa62373e69b4998a29ecec8f14a9e0a213a043ced8064c069d7e464b5fd3ccb92b45bd59b15c0e1bb27e3c366d43f86a9a6b5ad42647a1aad69a73ac50b19ae3ec978c2c70aa2010a99010a301c662f19abc461e7eddecf165adfa7fca569e209773f3db31241c1e297f0a8d5b3e4768828b065fbeb1d6776f61073f6121b3031202d20556e6d6173746572656420496d70756c7365732e377a187a22146170706c69636174696f6e2f782d6578742d377a32302eb61ea475017e28c013616a56c1219ba90dc35fffff453d9675146f648f66634e0d1516528d37aba9f5801229d9f2181a044e6f6e6542087465737420707562520062020801" + + signed_claim, err := DecodeClaimHex(signed_claim_hex, "lbrycrd_main") + if err != nil { + t.Error(err) + } + cert_claim, err := DecodeClaimHex(cert_claim_hex, "lbrycrd_main") + if err != nil { + t.Error(err) + } + + firstInputTxHash, err := GetOutpointHash("becb96a4a2e66bd24f083772fe9da904654ea9b5f07cc5bfbee233355911ddb1", uint32(0)) + if err != nil { + t.Error(err) + } + cert_id := "e67323a67a42307410f9679bf7fb344a428eb75c" + + result, err := signed_claim.ValidateClaimSignature(cert_claim, firstInputTxHash, cert_id, "lbrycrd_main") + if err != nil { + t.Error(err) + } + if result != true { + t.Error("failed to validate signature:", result) + } + +} + +func TestGetOutpointHash(t *testing.T) { + hash, err := GetOutpointHash("dc3dcf2f94d3c91e454ac2474802e20f26b30705372dda43890c811d918aef64", 1) + if err != nil { + t.Error(err) + } + assert.Assert(t, hash == "64ef8a911d810c8943da2d370507b3260fe2024847c24a451ec9d3942fcf3ddc01000000", uint(1)) +}