Skip to content

Commit c7426df

Browse files
committed
fix(certdb): use sql.NullString for CertificateRecord.CommonName
Rows inserted before the migration in #1126 will have the `common_name` set to NULL. This fixes selects for those rows.
1 parent 8e907d3 commit c7426df

File tree

3 files changed

+53
-2
lines changed

3 files changed

+53
-2
lines changed

certdb/certdb.go

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

33
import (
4+
"database/sql"
45
"encoding/json"
56
"time"
67

@@ -22,7 +23,7 @@ type CertificateRecord struct {
2223
NotBefore time.Time `db:"not_before"`
2324
MetadataJSON types.JSONText `db:"metadata"`
2425
SANsJSON types.JSONText `db:"sans"`
25-
CommonName string `db:"common_name"`
26+
CommonName sql.NullString `db:"common_name"`
2627
}
2728

2829
// SetMetadata sets the metadata json

certdb/sql/sql_test.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ func roughlySameTime(t1, t2 time.Time) bool {
5252
func testEverything(ta TestAccessor, t *testing.T) {
5353
testInsertCertificateAndGetCertificate(ta, t)
5454
testInsertCertificateAndGetUnexpiredCertificate(ta, t)
55+
testInsertCertificateAndGetUnexpiredCertificateNullCommonName(ta, t)
5556
testUpdateCertificateAndGetCertificate(ta, t)
5657
testInsertOCSPAndGetOCSP(ta, t)
5758
testInsertOCSPAndGetUnexpiredOCSP(ta, t)
@@ -153,6 +154,54 @@ func testInsertCertificateAndGetUnexpiredCertificate(ta TestAccessor, t *testing
153154
t.Error("Should have 1 unexpired certificate record:", len(unexpired))
154155
}
155156
}
157+
func testInsertCertificateAndGetUnexpiredCertificateNullCommonName(ta TestAccessor, t *testing.T) {
158+
ta.Truncate()
159+
160+
expiry := time.Now().Add(time.Minute)
161+
want := certdb.CertificateRecord{
162+
PEM: "fake cert data",
163+
Serial: "fake serial 2",
164+
AKI: fakeAKI,
165+
Status: "good",
166+
Reason: 0,
167+
Expiry: expiry,
168+
}
169+
170+
if err := ta.Accessor.InsertCertificate(want); err != nil {
171+
t.Fatal(err)
172+
}
173+
174+
// simulate situation where there are rows before migrate 002 has been run
175+
ta.DB.MustExec("update certificates set common_name = NULL")
176+
177+
rets, err := ta.Accessor.GetCertificate(want.Serial, want.AKI)
178+
if err != nil {
179+
t.Fatal(err)
180+
}
181+
182+
if len(rets) != 1 {
183+
t.Fatal("should return exactly one record")
184+
}
185+
186+
got := rets[0]
187+
188+
// reflection comparison with zero time objects are not stable as it seems
189+
if want.Serial != got.Serial || want.Status != got.Status ||
190+
want.AKI != got.AKI || !got.RevokedAt.IsZero() ||
191+
want.PEM != got.PEM || !roughlySameTime(got.Expiry, expiry) {
192+
t.Errorf("want Certificate %+v, got %+v", want, got)
193+
}
194+
195+
unexpired, err := ta.Accessor.GetUnexpiredCertificates()
196+
197+
if err != nil {
198+
t.Fatal(err)
199+
}
200+
201+
if len(unexpired) != 1 {
202+
t.Error("Should have 1 unexpired certificate record:", len(unexpired))
203+
}
204+
}
156205

157206
func testUpdateCertificateAndGetCertificate(ta TestAccessor, t *testing.T) {
158207
ta.Truncate()

signer/local/local.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"crypto/rand"
1010
"crypto/x509"
1111
"crypto/x509/pkix"
12+
"database/sql"
1213
"encoding/asn1"
1314
"encoding/hex"
1415
"encoding/pem"
@@ -517,7 +518,7 @@ func (s *Signer) Sign(req signer.SignRequest) (cert []byte, err error) {
517518
PEM: string(signedCert),
518519
IssuedAt: time.Now(),
519520
NotBefore: certTBS.NotBefore,
520-
CommonName: certTBS.Subject.CommonName,
521+
CommonName: sql.NullString{String: certTBS.Subject.CommonName, Valid: true},
521522
}
522523

523524
if err := certRecord.SetMetadata(req.Metadata); err != nil {

0 commit comments

Comments
 (0)