@@ -25,6 +25,7 @@ import (
2525
2626 "github.com/notaryproject/notation-core-go/signature"
2727 "github.com/notaryproject/notation-core-go/testhelper"
28+ gopkcs7 "go.mozilla.org/pkcs7"
2829)
2930
3031const testPayload = "test dm-verity root hash payload"
@@ -94,8 +95,10 @@ func TestSignParseVerifyRoundTrip(t *testing.T) {
9495 if len (content .SignerInfo .CertificateChain ) == 0 {
9596 t .Fatal ("Content() returned no certificates" )
9697 }
97- if content .Payload .ContentType != MediaTypeEnvelope {
98- t .Fatalf ("ContentType = %q, want %q" , content .Payload .ContentType , MediaTypeEnvelope )
98+ // PKCS#7 detached signatures don't carry the signed payload's content
99+ // type, so Content() reports it as unknown.
100+ if content .Payload .ContentType != "" {
101+ t .Fatalf ("ContentType = %q, want empty" , content .Payload .ContentType )
99102 }
100103}
101104
@@ -259,3 +262,68 @@ func (s *customSignSigner) Sign(payload []byte) ([]byte, []*x509.Certificate, er
259262 return sig , s .certs , nil
260263}
261264func (s * customSignSigner ) KeySpec () (signature.KeySpec , error ) { return s .keySpec , nil }
265+
266+ // TestSignRejectsEmptyPayload verifies that an empty Payload.Content is
267+ // rejected with InvalidSignRequestError.
268+ func TestSignRejectsEmptyPayload (t * testing.T ) {
269+ req := newSignRequest ()
270+ req .Payload .Content = nil
271+ _ , err := NewEnvelope ().Sign (req )
272+ var want * signature.InvalidSignRequestError
273+ if ! errors .As (err , & want ) {
274+ t .Fatalf ("want InvalidSignRequestError, got %T: %v" , err , err )
275+ }
276+ }
277+
278+ // TestSignRejectsNilLeafCertificate verifies that a signer returning a
279+ // nil leaf certificate is rejected with InvalidSignatureError.
280+ func TestSignRejectsNilLeafCertificate (t * testing.T ) {
281+ base := newRSATestSigner ()
282+ req := & signature.SignRequest {
283+ Payload : signature.Payload {ContentType : MediaTypeEnvelope , Content : []byte (testPayload )},
284+ Signer : & customSignSigner {
285+ certs : []* x509.Certificate {nil , base .certs [1 ]},
286+ keySpec : base .keySpec ,
287+ sign : func (payload []byte ) ([]byte , error ) {
288+ h := sha256 .Sum256 (payload )
289+ return rsa .SignPKCS1v15 (rand .Reader , base .key .(* rsa.PrivateKey ), crypto .SHA256 , h [:])
290+ },
291+ },
292+ }
293+ _ , err := NewEnvelope ().Sign (req )
294+ var want * signature.InvalidSignatureError
295+ if ! errors .As (err , & want ) {
296+ t .Fatalf ("want InvalidSignatureError, got %T: %v" , err , err )
297+ }
298+ }
299+
300+ // TestParseEnvelopeRejectsMultipleSigners verifies that the dm-verity
301+ // profile's "exactly one signer" guard fires on multi-signer envelopes.
302+ // Empty-EncryptedDigest is also exercised by FuzzSignaturePkcs7.
303+ func TestParseEnvelopeRejectsMultipleSigners (t * testing.T ) {
304+ tuple := testhelper .GetRSACertTuple (2048 )
305+ sd , err := gopkcs7 .NewSignedData ([]byte (testPayload ))
306+ if err != nil {
307+ t .Fatalf ("NewSignedData() error: %v" , err )
308+ }
309+ sd .SetDigestAlgorithm (gopkcs7 .OIDDigestAlgorithmSHA256 )
310+ sd .SetEncryptionAlgorithm (gopkcs7 .OIDEncryptionAlgorithmRSA )
311+ cfg := gopkcs7.SignerInfoConfig {}
312+ if err := sd .SignWithoutAttr (tuple .Cert , tuple .PrivateKey , cfg ); err != nil {
313+ t .Fatalf ("SignWithoutAttr() #1 error: %v" , err )
314+ }
315+ if err := sd .SignWithoutAttr (tuple .Cert , tuple .PrivateKey , cfg ); err != nil {
316+ t .Fatalf ("SignWithoutAttr() #2 error: %v" , err )
317+ }
318+ sd .Detach ()
319+ encoded , err := sd .Finish ()
320+ if err != nil {
321+ t .Fatalf ("Finish() error: %v" , err )
322+ }
323+
324+ _ , err = ParseEnvelope (encoded )
325+ var want * signature.InvalidSignatureError
326+ if ! errors .As (err , & want ) {
327+ t .Fatalf ("want InvalidSignatureError, got %T: %v" , err , err )
328+ }
329+ }
0 commit comments