Skip to content

Commit

Permalink
Merge pull request #740 from mozilla-services/fix-739-set-xpi-ee-not-…
Browse files Browse the repository at this point in the history
…before-to-utc-now

signer: revert XPI EE validity to the interval UTC now and 87600h later
  • Loading branch information
g-k authored Sep 1, 2021
2 parents d841e12 + 2405148 commit 019e766
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 27 deletions.
4 changes: 2 additions & 2 deletions signer/xpi/x509.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,8 @@ func (s *XPISigner) makeTemplate(cn string) *x509.Certificate {
Province: []string{"CA"},
Locality: []string{"Mountain View"},
},
NotBefore: EENotBefore,
NotAfter: EENotBefore.Add(87600 * time.Hour), // ten year
NotBefore: time.Now().UTC(),
NotAfter: time.Now().UTC().Add(87600 * time.Hour), // roughly ten years later
SignatureAlgorithm: s.issuerCert.SignatureAlgorithm,
KeyUsage: x509.KeyUsageDigitalSignature,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageCodeSigning},
Expand Down
20 changes: 20 additions & 0 deletions signer/xpi/x509_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"crypto/sha256"
"fmt"
"testing"
"time"

"go.mozilla.org/cose"
)
Expand Down Expand Up @@ -90,6 +91,25 @@ func TestMakeEndEntity(t *testing.T) {
}
})

t.Run("should set EE NotBefore to UTC now", func(t *testing.T) {
t.Parallel()

s := initSigner(t, 3)

testid := "foo"
cert, _, err := s.MakeEndEntity(testid, nil)
if err != nil {
t.Fatal(err)
}
timeSinceNotBefore := time.Now().UTC().Sub(cert.NotBefore)
if timeSinceNotBefore.Seconds() <= 0 {
t.Fatalf("cert is not yet valid; got %f seconds since EE NotBefore", timeSinceNotBefore.Seconds())
}
// see GH #739 for details
if timeSinceNotBefore.Minutes() > 5 {
t.Fatalf("more than five minutes since cert; got %f seconds since EE NotBefore", timeSinceNotBefore.Seconds())
}
})
}

func TestGetIssuerRSAKeySize(t *testing.T) {
Expand Down
8 changes: 0 additions & 8 deletions signer/xpi/xpi.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,6 @@ const (
rsaKeyMinSize = 2048
)

var (
// EENotBefore is the NotBefore value used in generated
// EE/leaf certs. Fx ignores EE certs when it verifies addons,
// but we pin it to 2020-01-01 so we can use existing chain
// verification logic in tests and the monitor
EENotBefore = time.Date(2020, time.January, 1, 0, 0, 0, 0, time.UTC)
)

// An XPISigner is configured to issue detached PKCS7 and COSE
// signatures for Firefox Add-ons of various types.
type XPISigner struct {
Expand Down
5 changes: 5 additions & 0 deletions tools/autograph-client/build_test_xpis.sh
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ else
COMMON_ARGS="-t $TARGET -f $INPUT_FILE -u $HAWK_USER -p $HAWK_SECRET -cn $CN -k $SIGNER_ID -r $TRUST_ROOTS -vt $VERIFICATION_TIME"
fi

VERIFY=${VERIFY:-"1"}
if [ "$VERIFY" = "0" ]; then
COMMON_ARGS="$COMMON_ARGS -noverify"
fi

# only PKCS7 SHA1
go run client.go $COMMON_ARGS -pk7digest sha1 -o ${OUTPUT_BASENAME}-SHA1.zip

Expand Down
47 changes: 31 additions & 16 deletions tools/autograph-client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ func main() {
var (
userid, pass, data, hash, url, infile, outfile, outkeyfile, keyid, cn, pk7digest, rootPath, verificationTimeInput string
iter, maxworkers, sa int
debug bool
debug, noVerify bool
err error
requests []formats.SignatureRequest
algs coseAlgs
Expand Down Expand Up @@ -140,13 +140,14 @@ examples:
flag.Var(&algs, "c", "a COSE Signature algorithm to sign an XPI with can be used multiple times")
flag.StringVar(&pk7digest, "pk7digest", "", "an optional PK7 digest algorithm to use for XPI file signing, either 'sha1' (default) or 'sha256'.")
flag.StringVar(&rootPath, "r", "/path/to/root.pem", "Path to a PEM file of root certificates")
flag.StringVar(&verificationTimeInput, "vt", "", "Time to verify XPI signatures at in RFC3339 format. Defaults to time.Now().")
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")
flag.BoolVar(&noVerify, "noverify", false, "Skip verifying successful responses. Default false.")

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

if verificationTimeInput == "" {
verificationTime = time.Now()
verificationTime = time.Now().UTC().Add(time.Minute)
if debug {
fmt.Printf("Using default verification time: %q\n", verificationTime)
}
Expand Down Expand Up @@ -279,7 +280,9 @@ examples:
)
switch response.Type {
case contentsignature.Type:
sigStatus = verifyContentSignature(input, response, req.URL.RequestURI())
if !noVerify {
sigStatus = verifyContentSignature(input, response, req.URL.RequestURI())
}
sig, err := csigverifier.Unmarshal(response.Signature)
if err != nil {
log.Fatal(err)
Expand All @@ -293,7 +296,9 @@ examples:
sigStr += sig.Mode + "=" + response.Signature + "\n"
sigData = []byte(sigStr)
case xpi.Type:
sigStatus = verifyXPI(input, request, response, reqType, roots, verificationTime)
if !noVerify {
sigStatus = verifyXPI(input, request, response, reqType, roots, verificationTime)
}
switch reqType {
case requestTypeData:
sigData, err = base64.StdEncoding.DecodeString(response.Signature)
Expand All @@ -310,33 +315,43 @@ examples:
if err != nil {
log.Fatal(err)
}
sigStatus = verifyAPK2(sigData)
if !noVerify {
sigStatus = verifyAPK2(sigData)
}
case mar.Type:
sigStatus = verifyMAR(input)
if !noVerify {
sigStatus = verifyMAR(input)
}
sigData, err = base64.StdEncoding.DecodeString(response.SignedFile)
if err != nil {
log.Fatal(err)
}
case genericrsa.Type:
err = genericrsa.VerifyGenericRsaSignatureResponse(input, response)
if err != nil {
log.Fatal(err)
if !noVerify {
err = genericrsa.VerifyGenericRsaSignatureResponse(input, response)
if err != nil {
log.Fatal(err)
}
sigStatus = true
}
sigStatus = true
sigData, err = base64.StdEncoding.DecodeString(response.Signature)
if err != nil {
log.Fatal(err)
}
case gpg2.Type:
sigStatus = verifyPGP(input, response.Signature, response.PublicKey)
if !noVerify {
sigStatus = verifyPGP(input, response.Signature, response.PublicKey)
}
sigData = []byte(response.Signature)
default:
log.Fatalf("unsupported signature type: %s", response.Type)
}
if sigStatus {
log.Printf("signature %d from signer %q passes", i, response.SignerID)
} else {
log.Fatalf("response %d from signer %q does not pass!", i, response.SignerID)
if !noVerify {
if sigStatus {
log.Printf("signature %d from signer %q passes", i, response.SignerID)
} else {
log.Fatalf("response %d from signer %q does not pass!", i, response.SignerID)
}
}
if outfile != "" {
err = ioutil.WriteFile(outfile, sigData, 0644)
Expand Down
2 changes: 1 addition & 1 deletion tools/autograph-client/integration_test_xpis.sh
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,5 @@ SIGNER_ID=${SIGNER_ID_PREFIX}extensions-ecdsa-expired-chain \
TRUST_ROOTS=dev-ext-ecdsa-expired-root.pem \
TARGET="$AUTOGRAPH_URL" \
CONFIG=${SIGNER_ID_PREFIX}extensions-ecdsa-expired-chain \
VERIFICATION_TIME="2020-01-01T01:01:01Z" \
VERIFY=0 \
./build_test_xpis.sh /app/src/autograph/signer/xpi/test/fixtures/ublock_origin-1.33.2-an+fx.xpi

0 comments on commit 019e766

Please sign in to comment.