Skip to content

Commit 019e766

Browse files
authored
Merge pull request #740 from mozilla-services/fix-739-set-xpi-ee-not-before-to-utc-now
signer: revert XPI EE validity to the interval UTC now and 87600h later
2 parents d841e12 + 2405148 commit 019e766

File tree

6 files changed

+59
-27
lines changed

6 files changed

+59
-27
lines changed

signer/xpi/x509.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,8 @@ func (s *XPISigner) makeTemplate(cn string) *x509.Certificate {
108108
Province: []string{"CA"},
109109
Locality: []string{"Mountain View"},
110110
},
111-
NotBefore: EENotBefore,
112-
NotAfter: EENotBefore.Add(87600 * time.Hour), // ten year
111+
NotBefore: time.Now().UTC(),
112+
NotAfter: time.Now().UTC().Add(87600 * time.Hour), // roughly ten years later
113113
SignatureAlgorithm: s.issuerCert.SignatureAlgorithm,
114114
KeyUsage: x509.KeyUsageDigitalSignature,
115115
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageCodeSigning},

signer/xpi/x509_test.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"crypto/sha256"
88
"fmt"
99
"testing"
10+
"time"
1011

1112
"go.mozilla.org/cose"
1213
)
@@ -90,6 +91,25 @@ func TestMakeEndEntity(t *testing.T) {
9091
}
9192
})
9293

94+
t.Run("should set EE NotBefore to UTC now", func(t *testing.T) {
95+
t.Parallel()
96+
97+
s := initSigner(t, 3)
98+
99+
testid := "foo"
100+
cert, _, err := s.MakeEndEntity(testid, nil)
101+
if err != nil {
102+
t.Fatal(err)
103+
}
104+
timeSinceNotBefore := time.Now().UTC().Sub(cert.NotBefore)
105+
if timeSinceNotBefore.Seconds() <= 0 {
106+
t.Fatalf("cert is not yet valid; got %f seconds since EE NotBefore", timeSinceNotBefore.Seconds())
107+
}
108+
// see GH #739 for details
109+
if timeSinceNotBefore.Minutes() > 5 {
110+
t.Fatalf("more than five minutes since cert; got %f seconds since EE NotBefore", timeSinceNotBefore.Seconds())
111+
}
112+
})
93113
}
94114

95115
func TestGetIssuerRSAKeySize(t *testing.T) {

signer/xpi/xpi.go

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,6 @@ const (
5656
rsaKeyMinSize = 2048
5757
)
5858

59-
var (
60-
// EENotBefore is the NotBefore value used in generated
61-
// EE/leaf certs. Fx ignores EE certs when it verifies addons,
62-
// but we pin it to 2020-01-01 so we can use existing chain
63-
// verification logic in tests and the monitor
64-
EENotBefore = time.Date(2020, time.January, 1, 0, 0, 0, 0, time.UTC)
65-
)
66-
6759
// An XPISigner is configured to issue detached PKCS7 and COSE
6860
// signatures for Firefox Add-ons of various types.
6961
type XPISigner struct {

tools/autograph-client/build_test_xpis.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ else
2626
COMMON_ARGS="-t $TARGET -f $INPUT_FILE -u $HAWK_USER -p $HAWK_SECRET -cn $CN -k $SIGNER_ID -r $TRUST_ROOTS -vt $VERIFICATION_TIME"
2727
fi
2828

29+
VERIFY=${VERIFY:-"1"}
30+
if [ "$VERIFY" = "0" ]; then
31+
COMMON_ARGS="$COMMON_ARGS -noverify"
32+
fi
33+
2934
# only PKCS7 SHA1
3035
go run client.go $COMMON_ARGS -pk7digest sha1 -o ${OUTPUT_BASENAME}-SHA1.zip
3136

tools/autograph-client/client.go

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ func main() {
6464
var (
6565
userid, pass, data, hash, url, infile, outfile, outkeyfile, keyid, cn, pk7digest, rootPath, verificationTimeInput string
6666
iter, maxworkers, sa int
67-
debug bool
67+
debug, noVerify bool
6868
err error
6969
requests []formats.SignatureRequest
7070
algs coseAlgs
@@ -140,13 +140,14 @@ examples:
140140
flag.Var(&algs, "c", "a COSE Signature algorithm to sign an XPI with can be used multiple times")
141141
flag.StringVar(&pk7digest, "pk7digest", "", "an optional PK7 digest algorithm to use for XPI file signing, either 'sha1' (default) or 'sha256'.")
142142
flag.StringVar(&rootPath, "r", "/path/to/root.pem", "Path to a PEM file of root certificates")
143-
flag.StringVar(&verificationTimeInput, "vt", "", "Time to verify XPI signatures at in RFC3339 format. Defaults to time.Now().")
143+
flag.StringVar(&verificationTimeInput, "vt", "", "Time to verify XPI signatures at in RFC3339 format. Defaults to at client invokation + 1 minute to account for time to transfer and sign the XPI")
144+
flag.BoolVar(&noVerify, "noverify", false, "Skip verifying successful responses. Default false.")
144145

145146
flag.BoolVar(&debug, "D", false, "debug logs: show raw requests & responses")
146147
flag.Parse()
147148

148149
if verificationTimeInput == "" {
149-
verificationTime = time.Now()
150+
verificationTime = time.Now().UTC().Add(time.Minute)
150151
if debug {
151152
fmt.Printf("Using default verification time: %q\n", verificationTime)
152153
}
@@ -279,7 +280,9 @@ examples:
279280
)
280281
switch response.Type {
281282
case contentsignature.Type:
282-
sigStatus = verifyContentSignature(input, response, req.URL.RequestURI())
283+
if !noVerify {
284+
sigStatus = verifyContentSignature(input, response, req.URL.RequestURI())
285+
}
283286
sig, err := csigverifier.Unmarshal(response.Signature)
284287
if err != nil {
285288
log.Fatal(err)
@@ -293,7 +296,9 @@ examples:
293296
sigStr += sig.Mode + "=" + response.Signature + "\n"
294297
sigData = []byte(sigStr)
295298
case xpi.Type:
296-
sigStatus = verifyXPI(input, request, response, reqType, roots, verificationTime)
299+
if !noVerify {
300+
sigStatus = verifyXPI(input, request, response, reqType, roots, verificationTime)
301+
}
297302
switch reqType {
298303
case requestTypeData:
299304
sigData, err = base64.StdEncoding.DecodeString(response.Signature)
@@ -310,33 +315,43 @@ examples:
310315
if err != nil {
311316
log.Fatal(err)
312317
}
313-
sigStatus = verifyAPK2(sigData)
318+
if !noVerify {
319+
sigStatus = verifyAPK2(sigData)
320+
}
314321
case mar.Type:
315-
sigStatus = verifyMAR(input)
322+
if !noVerify {
323+
sigStatus = verifyMAR(input)
324+
}
316325
sigData, err = base64.StdEncoding.DecodeString(response.SignedFile)
317326
if err != nil {
318327
log.Fatal(err)
319328
}
320329
case genericrsa.Type:
321-
err = genericrsa.VerifyGenericRsaSignatureResponse(input, response)
322-
if err != nil {
323-
log.Fatal(err)
330+
if !noVerify {
331+
err = genericrsa.VerifyGenericRsaSignatureResponse(input, response)
332+
if err != nil {
333+
log.Fatal(err)
334+
}
335+
sigStatus = true
324336
}
325-
sigStatus = true
326337
sigData, err = base64.StdEncoding.DecodeString(response.Signature)
327338
if err != nil {
328339
log.Fatal(err)
329340
}
330341
case gpg2.Type:
331-
sigStatus = verifyPGP(input, response.Signature, response.PublicKey)
342+
if !noVerify {
343+
sigStatus = verifyPGP(input, response.Signature, response.PublicKey)
344+
}
332345
sigData = []byte(response.Signature)
333346
default:
334347
log.Fatalf("unsupported signature type: %s", response.Type)
335348
}
336-
if sigStatus {
337-
log.Printf("signature %d from signer %q passes", i, response.SignerID)
338-
} else {
339-
log.Fatalf("response %d from signer %q does not pass!", i, response.SignerID)
349+
if !noVerify {
350+
if sigStatus {
351+
log.Printf("signature %d from signer %q passes", i, response.SignerID)
352+
} else {
353+
log.Fatalf("response %d from signer %q does not pass!", i, response.SignerID)
354+
}
340355
}
341356
if outfile != "" {
342357
err = ioutil.WriteFile(outfile, sigData, 0644)

tools/autograph-client/integration_test_xpis.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,5 @@ SIGNER_ID=${SIGNER_ID_PREFIX}extensions-ecdsa-expired-chain \
2525
TRUST_ROOTS=dev-ext-ecdsa-expired-root.pem \
2626
TARGET="$AUTOGRAPH_URL" \
2727
CONFIG=${SIGNER_ID_PREFIX}extensions-ecdsa-expired-chain \
28-
VERIFICATION_TIME="2020-01-01T01:01:01Z" \
28+
VERIFY=0 \
2929
./build_test_xpis.sh /app/src/autograph/signer/xpi/test/fixtures/ublock_origin-1.33.2-an+fx.xpi

0 commit comments

Comments
 (0)