Exemplo n.º 1
0
 def test_multiple_signers_different_hash_algs(self, backend):
     data = b"hello world"
     cert, key = _load_cert_key()
     rsa_key = load_vectors_from_file(
         os.path.join("x509", "custom", "ca", "rsa_key.pem"),
         lambda pemfile: serialization.load_pem_private_key(
             pemfile.read(), None),
         mode="rb",
     )
     rsa_cert = load_vectors_from_file(
         os.path.join("x509", "custom", "ca", "rsa_ca.pem"),
         loader=lambda pemfile: x509.load_pem_x509_certificate(pemfile.read(
         )),
         mode="rb",
     )
     builder = (smime.SMIMESignatureBuilder().set_data(data).add_signer(
         cert, key, hashes.SHA384()).add_signer(rsa_cert, rsa_key,
                                                hashes.SHA512()))
     options = []
     sig = builder.sign(serialization.Encoding.DER, options)
     # There should be two SHA384 and two SHA512 OIDs in this structure
     assert sig.count(b"\x06\t`\x86H\x01e\x03\x04\x02\x02") == 2
     assert sig.count(b"\x06\t`\x86H\x01e\x03\x04\x02\x03") == 2
     _smime_verify(
         serialization.Encoding.DER,
         sig,
         None,
         [cert, rsa_cert],
         options,
         backend,
     )
Exemplo n.º 2
0
    def test_smime_sign_no_capabilities(self, backend):
        data = b"hello world"
        cert, key = _load_cert_key()
        builder = (smime.SMIMESignatureBuilder().set_data(data).add_signer(
            cert, key, hashes.SHA256()))

        options = [smime.SMIMEOptions.NoCapabilities]
        sig_binary = builder.sign(serialization.Encoding.DER, options)
        # NoCapabilities removes the SMIMECapabilities attribute from the
        # PKCS7 structure. This is an ASN.1 sequence with the
        # OID 1.2.840.113549.1.9.15. It does NOT remove all authenticated
        # attributes, so we verify that by looking for the signingTime OID.

        # 1.2.840.113549.1.9.15 SMIMECapabilities as an ASN.1 DER encoded OID
        assert b"\x06\t*\x86H\x86\xf7\r\x01\t\x0f" not in sig_binary
        # 1.2.840.113549.1.9.5 signingTime as an ASN.1 DER encoded OID
        assert b"\x06\t*\x86H\x86\xf7\r\x01\t\x05" in sig_binary
        _smime_verify(
            serialization.Encoding.DER,
            sig_binary,
            None,
            [cert],
            options,
            backend,
        )
Exemplo n.º 3
0
    def test_smime_sign_detached(self, backend):
        data = b"hello world"
        cert, key = _load_cert_key()
        options = [smime.SMIMEOptions.DetachedSignature]
        builder = (smime.SMIMESignatureBuilder().set_data(data).add_signer(
            cert, key, hashes.SHA256()))

        sig = builder.sign(serialization.Encoding.PEM, options)
        sig_binary = builder.sign(serialization.Encoding.DER, options)
        # We don't have a generic ASN.1 parser available to us so we instead
        # will assert on specific byte sequences being present based on the
        # parameters chosen above.
        assert b"sha-256" in sig
        # Detached signature means that the signed data is *not* embedded into
        # the PKCS7 structure itself, but is present in the PEM serialization
        # as a separate section before the PKCS7 data. So we should expect to
        # have data in sig but not in sig_binary
        assert data in sig
        _smime_verify(serialization.Encoding.PEM, sig, data, [cert], options,
                      backend)
        assert data not in sig_binary
        _smime_verify(
            serialization.Encoding.DER,
            sig_binary,
            data,
            [cert],
            options,
            backend,
        )
Exemplo n.º 4
0
 def test_sign_invalid_options_text_no_detached(self):
     cert, key = _load_cert_key()
     builder = (smime.SMIMESignatureBuilder().set_data(b"test").add_signer(
         cert, key, hashes.SHA256()))
     options = [smime.SMIMEOptions.Text]
     with pytest.raises(ValueError):
         builder.sign(serialization.Encoding.PEM, options)
Exemplo n.º 5
0
    def test_smime_sign_text(self, backend):
        data = b"hello world"
        cert, key = _load_cert_key()
        builder = (smime.SMIMESignatureBuilder().set_data(data).add_signer(
            cert, key, hashes.SHA256()))

        options = [
            smime.SMIMEOptions.Text,
            smime.SMIMEOptions.DetachedSignature,
        ]
        sig_pem = builder.sign(serialization.Encoding.PEM, options)
        # The text option adds text/plain headers to the S/MIME message
        # These headers are only relevant in PEM mode, not binary, which is
        # just the PKCS7 structure itself.
        assert b"text/plain" in sig_pem
        # When passing the Text option the header is prepended so the actual
        # signed data is this.
        signed_data = b"Content-Type: text/plain\r\n\r\nhello world"
        _smime_verify(
            serialization.Encoding.PEM,
            sig_pem,
            signed_data,
            [cert],
            options,
            backend,
        )
Exemplo n.º 6
0
 def test_smime_sign_binary(self, backend):
     data = b"hello\nworld"
     cert, key = _load_cert_key()
     builder = (smime.SMIMESignatureBuilder().set_data(data).add_signer(
         cert, key, hashes.SHA256()))
     options = []
     sig_no_binary = builder.sign(serialization.Encoding.DER, options)
     sig_binary = builder.sign(serialization.Encoding.DER,
                               [smime.SMIMEOptions.Binary])
     # Binary prevents translation of LF to CR+LF (SMIME canonical form)
     # so data should not be present in sig_no_binary, but should be present
     # in sig_binary
     assert data not in sig_no_binary
     _smime_verify(
         serialization.Encoding.DER,
         sig_no_binary,
         None,
         [cert],
         options,
         backend,
     )
     assert data in sig_binary
     _smime_verify(
         serialization.Encoding.DER,
         sig_binary,
         None,
         [cert],
         options,
         backend,
     )
Exemplo n.º 7
0
    def test_sign_byteslike(self):
        data = bytearray(b"hello world")
        cert, key = _load_cert_key()
        options = [smime.SMIMEOptions.DetachedSignature]
        builder = (smime.SMIMESignatureBuilder().set_data(data).add_signer(
            cert, key, hashes.SHA256()))

        sig = builder.sign(serialization.Encoding.PEM, options)
        assert bytes(data) in sig
Exemplo n.º 8
0
 def test_sign_invalid_options_no_attrs_and_no_caps(self):
     cert, key = _load_cert_key()
     builder = (smime.SMIMESignatureBuilder().set_data(b"test").add_signer(
         cert, key, hashes.SHA256()))
     options = [
         smime.SMIMEOptions.NoAttributes,
         smime.SMIMEOptions.NoCapabilities,
     ]
     with pytest.raises(ValueError):
         builder.sign(serialization.Encoding.PEM, options)
Exemplo n.º 9
0
 def test_smime_sign_alternate_digests_detached_pem(self, hash_alg,
                                                    expected_value):
     data = b"hello world"
     cert, key = _load_cert_key()
     builder = (smime.SMIMESignatureBuilder().set_data(data).add_signer(
         cert, key, hash_alg))
     options = [smime.SMIMEOptions.DetachedSignature]
     sig = builder.sign(serialization.Encoding.PEM, options)
     # When in detached signature mode the hash algorithm is stored as a
     # byte string like "sha-384".
     assert expected_value in sig
Exemplo n.º 10
0
 def test_smime_sign_alternate_digests_der(self, hash_alg, expected_value,
                                           backend):
     data = b"hello world"
     cert, key = _load_cert_key()
     builder = (smime.SMIMESignatureBuilder().set_data(data).add_signer(
         cert, key, hash_alg))
     options = []
     sig = builder.sign(serialization.Encoding.DER, options)
     assert expected_value in sig
     _smime_verify(serialization.Encoding.DER, sig, None, [cert], options,
                   backend)
Exemplo n.º 11
0
    def test_smime_sign_attached(self, backend):
        data = b"hello world"
        cert, key = _load_cert_key()
        options = []
        builder = (smime.SMIMESignatureBuilder().set_data(data).add_signer(
            cert, key, hashes.SHA256()))

        sig_binary = builder.sign(serialization.Encoding.DER, options)
        # When not passing detached signature the signed data is embedded into
        # the PKCS7 structure itself
        assert data in sig_binary
        _smime_verify(
            serialization.Encoding.DER,
            sig_binary,
            None,
            [cert],
            options,
            backend,
        )
Exemplo n.º 12
0
    def test_smime_sign_smime_canonicalization(self, backend):
        data = b"hello\nworld"
        cert, key = _load_cert_key()
        builder = (smime.SMIMESignatureBuilder().set_data(data).add_signer(
            cert, key, hashes.SHA256()))

        options = []
        sig_binary = builder.sign(serialization.Encoding.DER, options)
        # LF gets converted to CR+LF (SMIME canonical form)
        # so data should not be present in the sig
        assert data not in sig_binary
        assert b"hello\r\nworld" in sig_binary
        _smime_verify(
            serialization.Encoding.DER,
            sig_binary,
            None,
            [cert],
            options,
            backend,
        )
Exemplo n.º 13
0
    def test_smime_sign_no_attributes(self, backend):
        data = b"hello world"
        cert, key = _load_cert_key()
        builder = (smime.SMIMESignatureBuilder().set_data(data).add_signer(
            cert, key, hashes.SHA256()))

        options = [smime.SMIMEOptions.NoAttributes]
        sig_binary = builder.sign(serialization.Encoding.DER, options)
        # NoAttributes removes all authenticated attributes, so we shouldn't
        # find SMIMECapabilities or signingTime.

        # 1.2.840.113549.1.9.15 SMIMECapabilities as an ASN.1 DER encoded OID
        assert b"\x06\t*\x86H\x86\xf7\r\x01\t\x0f" not in sig_binary
        # 1.2.840.113549.1.9.5 signingTime as an ASN.1 DER encoded OID
        assert b"\x06\t*\x86H\x86\xf7\r\x01\t\x05" not in sig_binary
        _smime_verify(
            serialization.Encoding.DER,
            sig_binary,
            None,
            [cert],
            options,
            backend,
        )
Exemplo n.º 14
0
 def test_sign_no_data(self):
     cert, key = _load_cert_key()
     builder = smime.SMIMESignatureBuilder().add_signer(
         cert, key, hashes.SHA256())
     with pytest.raises(ValueError):
         builder.sign(serialization.Encoding.PEM, [])
Exemplo n.º 15
0
 def test_sign_no_signer(self):
     builder = smime.SMIMESignatureBuilder().set_data(b"test")
     with pytest.raises(ValueError):
         builder.sign(serialization.Encoding.PEM, [])
Exemplo n.º 16
0
 def test_set_data_twice(self):
     builder = smime.SMIMESignatureBuilder().set_data(b"test")
     with pytest.raises(ValueError):
         builder.set_data(b"test")
Exemplo n.º 17
0
 def test_invalid_data(self):
     builder = smime.SMIMESignatureBuilder()
     with pytest.raises(TypeError):
         builder.set_data(u"not bytes")
Exemplo n.º 18
0
 def test_unsupported_hash_alg(self):
     cert, key = _load_cert_key()
     with pytest.raises(TypeError):
         smime.SMIMESignatureBuilder().add_signer(cert, key,
                                                  hashes.SHA512_256())
Exemplo n.º 19
0
 def test_sign_invalid_encoding(self):
     cert, key = _load_cert_key()
     builder = (smime.SMIMESignatureBuilder().set_data(b"test").add_signer(
         cert, key, hashes.SHA256()))
     with pytest.raises(ValueError):
         builder.sign(serialization.Encoding.Raw, [])
Exemplo n.º 20
0
 def test_not_a_cert(self):
     cert, key = _load_cert_key()
     with pytest.raises(TypeError):
         smime.SMIMESignatureBuilder().add_signer(b"notacert", key,
                                                  hashes.SHA256())
Exemplo n.º 21
0
 def test_unsupported_key_type(self, backend):
     cert, _ = _load_cert_key()
     key = ed25519.Ed25519PrivateKey.generate()
     with pytest.raises(TypeError):
         smime.SMIMESignatureBuilder().add_signer(cert, key,
                                                  hashes.SHA256())