1###### Coverage stub
2import atexit
3import coverage
4cov = coverage.coverage(data_file='.coverage', cover_pylib=True)
5cov.start()
6# Register an exist handler that will print coverage
7def exit_handler():
8 cov.stop()
9 cov.save()
10atexit.register(exit_handler)
11####### End of coverage stub
12# Copyright 2025 The Sigstore Authors
13#
14# Licensed under the Apache License, Version 2.0 (the "License");
15# you may not use this file except in compliance with the License.
16# You may obtain a copy of the License at
17#
18# http://www.apache.org/licenses/LICENSE-2.0
19#
20# Unless required by applicable law or agreed to in writing, software
21# distributed under the License is distributed on an "AS IS" BASIS,
22# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23# See the License for the specific language governing permissions and
24# limitations under the License.
25
26import os
27import sys
28import tempfile
29
30# type: ignore
31import atheris
32from cryptography.hazmat.primitives import serialization
33
34import model_signing
35
36
37def TestOneInput(data):
38 """Fuzzer running on OSS-Fuzz.
39
40 Create a random model and key file,
41 then sign with the random key file.
42 Parse the key early to ignore if invalid.
43 """
44 fdp = atheris.FuzzedDataProvider(data)
45
46 pubkey_size = fdp.ConsumeIntInRange(0, 8 * 1024)
47 key_bytes = fdp.ConsumeBytes(pubkey_size)
48 try:
49 serialization.load_pem_private_key(
50 key_bytes, password=None, unsafe_skip_rsa_key_validation=True
51 )
52 except ValueError as e:
53 print(e)
54 return
55
56 with tempfile.TemporaryDirectory(prefix="mt_sign_only_") as tmpdir:
57 model_path = os.path.join(tmpdir, "model.bin")
58 model_size = fdp.ConsumeIntInRange(0, 64 * 1024)
59 with open(model_path, "wb") as f:
60 f.write(fdp.ConsumeBytes(model_size))
61
62 key_path = os.path.join(tmpdir, "fuzz.priv")
63 with open(key_path, "wb") as f:
64 f.write(key_bytes)
65
66 sig_path = os.path.join(tmpdir, "model.sig")
67
68 scfg = model_signing.signing.Config()
69 signer = scfg.use_elliptic_key_signer(private_key=key_path)
70 _ = signer.sign(model_path, sig_path)
71
72
73def main():
74 atheris.instrument_all()
75 atheris.Setup(sys.argv, TestOneInput)
76 atheris.Fuzz()
77
78
79if __name__ == "__main__":
80 main()