Skip to content

Commit 87afb57

Browse files
committed
demo: fix UnusedBit panic on signing error
1 parent 6795e4f commit 87afb57

2 files changed

Lines changed: 88 additions & 2 deletions

File tree

demo/encode.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -406,8 +406,9 @@ func CreateCertificate(config *CAConfig, issuanceLog *MerkleTree, cosigners []*C
406406
}
407407
})
408408
if certConfig.UnusedBit {
409-
if sig, err := certSig.Bytes(); err == nil && len(sig) == 0 || sig[len(sig)-1]&1 != 0 {
410-
certSig.SetError(errors.New("last bit in signature with not zero, unable to encode as unused"))
409+
sig, err := certSig.Bytes()
410+
if err == nil && (len(sig) == 0 || sig[len(sig)-1]&1 != 0) {
411+
certSig.SetError(errors.New("last bit in signature is not zero, unable to encode as unused"))
411412
return
412413
}
413414
}

demo/encode_unusedbit_test.go

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package main
2+
3+
import (
4+
"crypto"
5+
"crypto/ed25519"
6+
"errors"
7+
"io"
8+
"testing"
9+
"time"
10+
)
11+
12+
type failingSigner struct{}
13+
14+
func (failingSigner) Public() crypto.PublicKey {
15+
return ed25519.PublicKey(make([]byte, ed25519.PublicKeySize))
16+
}
17+
18+
func (failingSigner) Sign(io.Reader, []byte, crypto.SignerOpts) ([]byte, error) {
19+
return nil, errors.New("simulated signing failure")
20+
}
21+
22+
func TestCreateCertificateUnusedBitCosignerError(t *testing.T) {
23+
issuer, ok := TrustAnchorIDFromString("32473.1")
24+
if !ok {
25+
t.Fatalf("could not make issuer trust anchor ID")
26+
}
27+
cosignerID, ok := TrustAnchorIDFromString("32473.2")
28+
if !ok {
29+
t.Fatalf("could not make cosigner trust anchor ID")
30+
}
31+
32+
publicKey := []byte{
33+
0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02,
34+
0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03,
35+
0x42, 0x00, 0x04, 0xe6, 0x2b, 0x69, 0xe2, 0xbf, 0x65, 0x9f, 0x97, 0xbe,
36+
0x2f, 0x1e, 0x0d, 0x94, 0x8a, 0x4c, 0xd5, 0x97, 0x6b, 0xb7, 0xa9, 0x1e,
37+
0x0d, 0x46, 0xfb, 0xdd, 0xa9, 0xa9, 0x1e, 0x9d, 0xdc, 0xba, 0x5a, 0x01,
38+
0xe7, 0xd6, 0x97, 0xa8, 0x0a, 0x18, 0xf9, 0xc3, 0xc4, 0xa3, 0x1e, 0x56,
39+
0xe2, 0x7c, 0x83, 0x48, 0xdb, 0x16, 0x1a, 0x1c, 0xf5, 0x1d, 0x7e, 0xf1,
40+
0x94, 0x2d, 0x4b, 0xcf, 0x72, 0x22, 0xc1,
41+
}
42+
43+
entry := &EntryConfig{
44+
PublicKey: publicKey,
45+
CertConfigBase: CertConfigBase{
46+
NotBefore: time.Unix(1577836800, 0),
47+
NotAfter: time.Unix(1609459199, 0),
48+
},
49+
}
50+
51+
logEntry, err := MarshalTBSCertificateLogEntry(VersionPlants04, issuer, entry)
52+
if err != nil {
53+
t.Fatalf("MarshalTBSCertificateLogEntry: %s", err)
54+
}
55+
tree := NewMerkleTree([][]byte{logEntry})
56+
57+
config := &CAConfig{
58+
Version: VersionPlants04,
59+
ID: issuer,
60+
LogNumber: 1,
61+
}
62+
63+
failingCosigner := &Cosigner{
64+
Version: VersionPlants04,
65+
ID: cosignerID,
66+
SignatureAlgorithm: SignatureAlgorithmEd25519,
67+
Signer: failingSigner{},
68+
SignerOpts: crypto.Hash(0),
69+
}
70+
71+
certConfig := &CertificateConfig{
72+
Cosigners: []TrustAnchorID{cosignerID},
73+
UnusedBit: true,
74+
}
75+
76+
defer func() {
77+
if r := recover(); r != nil {
78+
t.Fatalf("CreateCertificate panicked instead of returning an error: %v", r)
79+
}
80+
}()
81+
82+
if _, err := CreateCertificate(config, tree, []*Cosigner{failingCosigner}, entry, certConfig, 0, 0, 1); err == nil {
83+
t.Fatalf("CreateCertificate succeeded, want an error from the failing cosigner")
84+
}
85+
}

0 commit comments

Comments
 (0)