Skip to content

Commit caec21f

Browse files
authored
Merge pull request #195 from b-open-io/pr-190
fix: address remaining code review issues from PR #190
2 parents 07ebec3 + d9877b1 commit caec21f

File tree

4 files changed

+75
-31
lines changed

4 files changed

+75
-31
lines changed

CHANGELOG.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ All notable changes to this project will be documented in this file. The format
44

55
## Table of Contents
66

7+
- [1.2.3 - 2025-06-30](#123---2025-06-30)
78
- [1.2.2 - 2025-06-27](#122---2025-06-27)
89
- [1.2.1 - 2025-06-12](#121---2025-06-12)
910
- [1.2.0 - 2025-06-10](#120---2025-06-10)
@@ -37,6 +38,28 @@ All notable changes to this project will be documented in this file. The format
3738
- [1.1.0 - 2024-08-19](#110---2024-08-19)
3839
- [1.0.0 - 2024-06-06](#100---2024-06-06)
3940

41+
## [1.2.3] - 2025-06-30
42+
43+
### Added
44+
- Enhanced peer authentication with proper message handling at receiver side
45+
- Centralized certificate exchange logic with new `sendCertificates` method
46+
- Added `SignCertificateWithWalletForTest` for wallet-based certificate signing in tests
47+
- Implemented proper nonce creation/verification using `utils.CreateNonce` and `utils.VerifyNonce`
48+
49+
### Changed
50+
- Updated `AUTH_PROTOCOL_ID` from "authrite message signature" to "auth message signature"
51+
- Changed `AuthMessage` JSON marshaling to use `wallet.BytesList` for Payload and Signature fields
52+
- Enhanced signature creation/verification to use wallet methods with explicit protocol details
53+
- Improved mock wallet with `VerifyHMAC` implementation
54+
55+
### Fixed
56+
- Fixed base64 concatenation bug in peer authentication nonce handling
57+
- Fixed certificate signing bug in `certificate_debug.go`
58+
- Fixed `TestPeerCertificateExchange` test to properly encrypt certificate fields
59+
- Improved error handling consistency using `NewAuthError`
60+
- Fixed variable naming consistency
61+
- Enhanced session state management and error messages throughout auth flow
62+
4063
## [1.2.2] - 2025-06-27
4164
### Added
4265
- New `CurrentHeight` function on chaintracker interface

auth/peer.go

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -494,15 +494,21 @@ func (p *Peer) handleInitialRequest(ctx context.Context, message *AuthMessage, s
494494
Certificates: certs,
495495
}
496496

497-
data := message.InitialNonce + session.SessionNonce
498-
sigData, err := base64.StdEncoding.DecodeString(data)
497+
// Decode the nonces first before concatenating
498+
initialNonceBytes, err := base64.StdEncoding.DecodeString(message.InitialNonce)
499499
if err != nil {
500-
return NewAuthError("failed to prepare data to sign", err)
500+
return NewAuthError("failed to decode initial nonce", err)
501501
}
502+
sessionNonceBytes, err := base64.StdEncoding.DecodeString(session.SessionNonce)
503+
if err != nil {
504+
return NewAuthError("failed to decode session nonce", err)
505+
}
506+
// Concatenate the decoded bytes
507+
sigData := append(initialNonceBytes, sessionNonceBytes...)
502508

503509
keyID := fmt.Sprintf("%s %s", message.InitialNonce, session.SessionNonce)
504510

505-
arg := wallet.CreateSignatureArgs{
511+
args := wallet.CreateSignatureArgs{
506512
EncryptionArgs: wallet.EncryptionArgs{
507513
ProtocolID: wallet.Protocol{
508514
// SecurityLevel set to 2 (SecurityLevelEveryAppAndCounterparty) as specified in BRC-31 (Authrite)
@@ -515,13 +521,12 @@ func (p *Peer) handleInitialRequest(ctx context.Context, message *AuthMessage, s
515521
Counterparty: message.IdentityKey,
516522
},
517523
},
518-
// Sign the certificate request data, as in TypeScript
519524
Data: sigData,
520525
}
521526

522-
sigResult, err := p.wallet.CreateSignature(ctx, arg, "")
527+
sigResult, err := p.wallet.CreateSignature(ctx, args, "")
523528
if err != nil {
524-
return fmt.Errorf("failed to sign initial response: %w", err)
529+
return NewAuthError("failed to sign initial response", err)
525530
}
526531

527532
response.Signature = sigResult.Signature.Serialize()
@@ -545,16 +550,21 @@ func (p *Peer) handleInitialResponse(ctx context.Context, message *AuthMessage,
545550
return ErrSessionNotFound
546551
}
547552

548-
data := message.InitialNonce + session.SessionNonce
549-
550-
sigData, err := base64.StdEncoding.DecodeString(data)
553+
// Decode the nonces first before concatenating
554+
initialNonceBytes, err := base64.StdEncoding.DecodeString(message.InitialNonce)
555+
if err != nil {
556+
return NewAuthError("failed to decode initial nonce", err)
557+
}
558+
sessionNonceBytes, err := base64.StdEncoding.DecodeString(session.SessionNonce)
551559
if err != nil {
552-
return NewAuthError("failed to prepare data to sign", err)
560+
return NewAuthError("failed to decode session nonce", err)
553561
}
562+
// Concatenate the decoded bytes
563+
sigData := append(initialNonceBytes, sessionNonceBytes...)
554564

555565
signature, err := ec.ParseSignature(message.Signature)
556566
if err != nil {
557-
return fmt.Errorf("failed to parse signature: %w", err)
567+
return NewAuthError("failed to parse signature", err)
558568
}
559569

560570
verifyResult, err := p.wallet.VerifySignature(ctx, wallet.VerifySignatureArgs{
@@ -612,13 +622,13 @@ func (p *Peer) handleInitialResponse(ctx context.Context, message *AuthMessage,
612622
utilsRequestedCerts,
613623
)
614624
if err != nil {
615-
return fmt.Errorf("invalid certificates: %w", err)
625+
return NewAuthError("invalid certificates", err)
616626
}
617627

618628
for _, callback := range p.onCertificateReceivedCallbacks {
619629
err := callback(senderPublicKey, message.Certificates)
620630
if err != nil {
621-
return fmt.Errorf("certificate received callback error: %w", err)
631+
return NewAuthError("certificate received callback error", err)
622632
}
623633
}
624634
}
@@ -638,7 +648,7 @@ func (p *Peer) handleInitialResponse(ctx context.Context, message *AuthMessage,
638648
if len(message.RequestedCertificates.Certifiers) > 0 || len(message.RequestedCertificates.CertificateTypes) > 0 {
639649
err = p.sendCertificates(ctx, message)
640650
if err != nil {
641-
return fmt.Errorf("failed to send requested certificates: %w", err)
651+
return NewAuthError("failed to send requested certificates", err)
642652
}
643653
}
644654

@@ -712,7 +722,7 @@ func (p *Peer) handleCertificateRequest(ctx context.Context, message *AuthMessag
712722
// Try to parse the signature
713723
signature, err := ec.ParseSignature(message.Signature)
714724
if err != nil {
715-
return fmt.Errorf("failed to parse signature: %w", err)
725+
return NewAuthError("failed to parse signature", err)
716726
}
717727

718728
// Verify signature
@@ -740,7 +750,7 @@ func (p *Peer) handleCertificateRequest(ctx context.Context, message *AuthMessag
740750
if len(message.RequestedCertificates.Certifiers) > 0 || len(message.RequestedCertificates.CertificateTypes) > 0 {
741751
err = p.sendCertificates(ctx, message)
742752
if err != nil {
743-
return fmt.Errorf("failed to send requested certificates: %w", err)
753+
return NewAuthError("failed to send requested certificates", err)
744754
}
745755
}
746756

@@ -776,7 +786,7 @@ func (p *Peer) handleCertificateResponse(ctx context.Context, message *AuthMessa
776786
// Try to parse the signature
777787
signature, err := ec.ParseSignature(message.Signature)
778788
if err != nil {
779-
return fmt.Errorf("failed to parse signature: %w", err)
789+
return NewAuthError("failed to parse signature", err)
780790
}
781791

782792
// Verify signature
@@ -865,7 +875,7 @@ func (p *Peer) handleGeneralMessage(ctx context.Context, message *AuthMessage, s
865875
// Try to parse the signature
866876
signature, err := ec.ParseSignature(message.Signature)
867877
if err != nil {
868-
return fmt.Errorf("failed to parse signature: %w", err)
878+
return NewAuthError("failed to parse signature", err)
869879
}
870880

871881
// Verify signature

auth/peer_test.go

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package auth
22

33
import (
4+
"bytes"
45
"context"
56
"encoding/base64"
67
"fmt"
@@ -405,7 +406,6 @@ func (t *LoggingMockTransport) OnData(callback func(context.Context, *AuthMessag
405406

406407
// TestPeerCertificateExchange tests certificate request and exchange
407408
func TestPeerCertificateExchange(t *testing.T) {
408-
t.Skip("Needs a fix for DecryptFields - probably something in test setup need to be adjusted")
409409

410410
var certType = tu.GetByte32FromString("testCertType")
411411
requiredField := "testField"
@@ -451,13 +451,23 @@ func TestPeerCertificateExchange(t *testing.T) {
451451
return &wallet.VerifySignatureResult{Valid: true}, nil
452452
}
453453

454-
// Create raw certificates with proper base64 encoding using our helper
454+
// Generate a symmetric key for field encryption
455+
fieldSymmetricKeyBytes := bytes.Repeat([]byte{1}, 32)
456+
fieldSymmetricKey := ec.NewSymmetricKey(fieldSymmetricKeyBytes)
457+
458+
// Encrypt the field value
459+
plainFieldValue := []byte("decrypted field value")
460+
encryptedFieldBytes, err := fieldSymmetricKey.Encrypt(plainFieldValue)
461+
require.NoError(t, err)
462+
encryptedFieldValue := base64.StdEncoding.EncodeToString(encryptedFieldBytes)
463+
464+
// Create raw certificates with encrypted fields
455465
aliceCertRaw := wallet.Certificate{
456466
Type: certType,
457467
SerialNumber: tu.GetByte32FromString("serial1"),
458468
Subject: aliceSubject,
459469
Certifier: bobSubject,
460-
Fields: map[string]string{requiredField: "fieldValue"},
470+
Fields: map[string]string{requiredField: encryptedFieldValue},
461471
RevocationOutpoint: tu.OutpointFromString(t, "a755810c21e17183ff6db6685f0de239fd3a0a3c0d4ba7773b0b0d1748541e2b.0"),
462472
}
463473

@@ -466,7 +476,7 @@ func TestPeerCertificateExchange(t *testing.T) {
466476
SerialNumber: tu.GetByte32FromString("serial2"),
467477
Subject: bobSubject,
468478
Certifier: aliceSubject,
469-
Fields: map[string]string{requiredField: "fieldValue"},
479+
Fields: map[string]string{requiredField: encryptedFieldValue},
470480
RevocationOutpoint: tu.OutpointFromString(t, "a755810c21e17183ff6db6685f0de239fd3a0a3c0d4ba7773b0b0d1748541e2b.1"),
471481
}
472482

@@ -510,28 +520,29 @@ func TestPeerCertificateExchange(t *testing.T) {
510520
logger.Printf("DEBUG: Alice cert signature: %x", aliceCert.Signature)
511521
logger.Printf("DEBUG: Bob cert signature: %x", bobCert.Signature)
512522

513-
// Create mock keyring results - also properly encoded
514-
fieldValueBase64 := base64.StdEncoding.EncodeToString([]byte("key-for-field"))
523+
// Mock keyring - in real usage this would be the symmetric key encrypted for the verifier
524+
// For testing, we just need valid encrypted data that MockDecrypt can "decrypt" to fieldSymmetricKeyBytes
525+
encryptedSymmetricKey := base64.StdEncoding.EncodeToString(fieldSymmetricKeyBytes)
515526
aliceWallet.MockProveCertificate = func(ctx context.Context, args wallet.ProveCertificateArgs, originator string) (*wallet.ProveCertificateResult, error) {
516527
return &wallet.ProveCertificateResult{
517-
KeyringForVerifier: map[string]string{requiredField: fieldValueBase64},
528+
KeyringForVerifier: map[string]string{requiredField: encryptedSymmetricKey},
518529
}, nil
519530
}
520531
bobWallet.MockProveCertificate = func(ctx context.Context, args wallet.ProveCertificateArgs, originator string) (*wallet.ProveCertificateResult, error) {
521532
return &wallet.ProveCertificateResult{
522-
KeyringForVerifier: map[string]string{requiredField: fieldValueBase64},
533+
KeyringForVerifier: map[string]string{requiredField: encryptedSymmetricKey},
523534
}, nil
524535
}
525536

526-
// Configure wallet mocks for Decrypt to make DecryptFields work
537+
// MockDecrypt returns the symmetric key for field decryption
527538
aliceWallet.MockDecrypt = func(ctx context.Context, args wallet.DecryptArgs, originator string) (*wallet.DecryptResult, error) {
528539
return &wallet.DecryptResult{
529-
Plaintext: []byte("decrypted field value"),
540+
Plaintext: fieldSymmetricKeyBytes,
530541
}, nil
531542
}
532543
bobWallet.MockDecrypt = func(ctx context.Context, args wallet.DecryptArgs, originator string) (*wallet.DecryptResult, error) {
533544
return &wallet.DecryptResult{
534-
Plaintext: []byte("decrypted field value"),
545+
Plaintext: fieldSymmetricKeyBytes,
535546
}, nil
536547
}
537548

auth/utils/certificate_debug.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ func SignCertificateWithWalletForTest(ctx context.Context, cert wallet.Certifica
8282
return encodedCert, fmt.Errorf("failed to get identity key of signer: %w", err)
8383
}
8484

85-
cert.Certifier = publicKeyResult.PublicKey
85+
encodedCert.Certifier = publicKeyResult.PublicKey
8686

8787
certObj, err := certificates.FromWalletCertificate(&encodedCert)
8888
if err != nil {

0 commit comments

Comments
 (0)