mirror of
https://github.com/OPCFoundation/UA-.NETStandard.git
synced 2026-10-18 06:31:35 +08:00
Certificates.Fuzz: expand corpus diversity + drop completed assessment doc (audit follow-up #2)
Expanded the Certificates fuzz corpus from 9 seeds to 21 (+ 12) across
all five categories. The security assessment doc flagged the corpus as
"adequate but limited diversity" -- this commit closes the gap.
Generator (Fuzzing/Opc.Ua.Certificates.Fuzz.Tools/Certificates.Testcases.cs)
now produces, in addition to the original RSA application cert / CRL /
CSR / PEM / extension seeds:
X509Cert/ certificate-expired.der RSA cert with NotAfter in past
certificate-selfsigned.der RSA cert with no separate issuer
certificate-ecc.der P-256 ECC cert with ECC issuer
X509CRL/ crl-multi-revoked.der CRL listing 3 revoked entries
crl-empty.der CRL with no revoked entries
X509CSR/ request-ecc.der ECC-signed PKCS#10 CSR
request-multi-san.der CSR with 4 SAN entries
PEM/ certificate-ecc.pem ECC PEM cert
private-key-ecc.pem ECC PEM private key
ASN1/ nested-sequence.der SEQUENCE containing inner SEQUENCE + OCTET STRING
large-integer.der 256-bit BigInteger (past AsnReader fast paths)
subject-alt-name-many.der SAN with 9 entries (5 DNS + 4 IP)
Exercises code paths the original corpus missed:
- ECDsa decode branches in cert + PEM + PKCS#10 parsers
- CRL revoked-list loop with multiple entries + empty-list boundary
- Validity-window logic for expired cert
- Self-signed (no chain) decode path
- Multi-entry SAN decode loop
- AsnReader.ReadInteger multi-limb branch (past 32 / 64-bit fast paths)
- Nested OCTET STRING containing further DER content
A dedicated ECC issuer ("CN=Fuzzing Test ECC Root") is constructed
because CertificateBuilder.CreateForECDsa() signs with the issuer's
ECDsa private key, so an RSA-only issuer is rejected.
Verified (net10.0):
- Opc.Ua.Certificates.Fuzz.Tests: 460 passed (up from 220), 0 failed.
The doubling reflects the 12 new seeds * the harness's
Fuzz*Assets/FuzzGoodTestcases theory expansion across the 20 cert
targets.
- Opc.Ua.Encoders.Fuzz.Tests baseline: 4131/4131 passed.
- Opc.Ua.Network.Fuzz.Tests baseline: 330/330 passed.
- Combined: 4921 passed, 0 failed.
DER seed files are committed via `git add -f` because the repo-wide
`*.der` gitignore would otherwise exclude them (matches the original
F2 commit's precedent of force-adding cert test seeds).
Side effect: deleted plans/security-assessment.md. The doc was an
untracked working-copy audit summary that has now had every item
addressed:
- 7.1 #1 (MUST FIX, parser bound): commit 77441468
- 7.2 #2 (corpus diversity): this commit
- 7.2 #3 (IOORE whitelist): commit 80832f17
- 7.3 future work: explicitly out-of-scope, tracked
in the PR description instead.
Audit ref: section 7.2 #2 of the security assessment doc.
This commit is contained in:
@@ -0,0 +1 @@
|
||||
�������������������������������
|
||||
@@ -0,0 +1 @@
|
||||
00
|
||||
Binary file not shown.
@@ -0,0 +1,15 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICVTCCAfugAwIBAgIKYvusxca3VI3UgzAKBggqhkjOPQQDAjA5MRcwFQYDVQQK
|
||||
Ew5PUEMgRm91bmRhdGlvbjEeMBwGA1UEAxMVRnV6emluZyBUZXN0IEVDQyBSb290
|
||||
MB4XDTI2MDYxMDEwMTAxOFoXDTI2MDYyMTEwMTAxOFowNDEXMBUGA1UEChMOT1BD
|
||||
IEZvdW5kYXRpb24xGTAXBgNVBAMTEEZ1enppbmcgVGVzdCBFQ0MwWTATBgcqhkjO
|
||||
PQIBBggqhkjOPQMBBwNCAAST+hLKMNeX8RHhHzqiFaJwIDeXN9pqxrBnIjABB8TQ
|
||||
LQcuChVDfvKPsbXxPdA0MtlcYKhd2BfSQgrrSJpuEWVfo4HvMIHsMAwGA1UdEwEB
|
||||
/wQCMAAwHQYDVR0OBBYEFIEKGI8SMS/38Mv6tzteKPF0fjXOMHQGA1UdIwRtMGuA
|
||||
FB4nQQHCqSJQ+4rm2JULxAjiTRaUoT2kOzA5MRcwFQYDVQQKEw5PUEMgRm91bmRh
|
||||
dGlvbjEeMBwGA1UEAxMVRnV6emluZyBUZXN0IEVDQyBSb290ghR9hdEvvFzBuK/k
|
||||
kqJwx/AREzG6WDAOBgNVHQ8BAf8EBAMCA8gwNwYDVR0RBDAwLoYhdXJuOm9wY2Zv
|
||||
dW5kYXRpb24ub3JnOmZ1enppbmc6ZWNjgglsb2NhbGhvc3QwCgYIKoZIzj0EAwID
|
||||
SAAwRQIgXJi8Jdaq0DzrwMrAu1GG2q98D6aSfvKOtvZ0BzCYy1kCIQCagVXXupku
|
||||
/qdEVzdaTC9ZQfY3nXR5hmFGQyLgcQUmug==
|
||||
-----END CERTIFICATE-----
|
||||
@@ -1,24 +1,24 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
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
|
||||
rAuaTOpGC6VkvC9d5rX7MtmiuxzBAMfA+ZnA
|
||||
DQEBCwUAA4IBAQAvw105dzRd3kT2f1yQJThC3J5qO+ZjygPj26Vo9tUTvjJdyzFD
|
||||
5xEiUl5KIG2zr9MhyXS/hvJd/7M9/QgZxPYBtrkzLK5f8223eLZ1nSKEhp0Ijq8K
|
||||
foP6Ryf3YpfsBJN1yoRxqh1PBfiYTSk5zXyTM5T4E8CGGCeAUXW1yfVE83WqxTgF
|
||||
7vU8Nf3ctOinq/FRTF6MseC3mRjT6WuK8qX1Z8kKvAN0y+bvalzcMP1qNS/uinrn
|
||||
oQT6nZ+Wis34jHdKas+0CPp36ON2ge+b3eFvpykmNqbifgNc+nbzZyTwhCQnQKEX
|
||||
h08/4ydC8EgN9ZBqpO41grqox+R4UT3SmItd
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIGiAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQgsh14JVtycxaZATYO
|
||||
DNP9a378mCN+AXKoK1Nssgw69MCgCgYIKoZIzj0DAQehRANCAAST+hLKMNeX8RHh
|
||||
HzqiFaJwIDeXN9pqxrBnIjABB8TQLQcuChVDfvKPsbXxPdA0MtlcYKhd2BfSQgrr
|
||||
SJpuEWVfoA0wCwYDVR0PMQQDAgCA
|
||||
-----END PRIVATE KEY-----
|
||||
@@ -1,28 +1,28 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDgf0mle3Ww+8Zt
|
||||
5bksTBcj61ARPtExUQ1LM7eDUXsR8A4RJ9/D7LXDiMBSgWilZoMF625USwd3cIaR
|
||||
/s+kUMWu9CKfMP8mCzyN+RiYcT0FOoutS7cAtnaMfZpY1mktZiif3jnccG9U+Epi
|
||||
2wv56iheuzHZ8WSzMnDWLkVgqpmk3TwJMQMg898MG8W3wkUEfQusTmWQYfg/S5Fq
|
||||
VVklRhtXY8C2mTPyOIn9ssKm1O/+FltUjpYGL28AeKJJHL22BFWPkdj3qVc4tpg5
|
||||
FRqL88d+oL7hNzLt3X9ngmd5TS/gRXfqsh3ZZWSorJCypeBfvnIk1nqkVl0TN5Wn
|
||||
JfnaORXxAgMBAAECggEADA7KJdk7uQXM4po0F+z+US+SXVrCYaO40xE0ChmWQqBi
|
||||
IQnDOwK7wITXz5ajyD55SxgaFOzyubeRgsXs4SZ1d7AlK+e1zJVN61I1v/pVDLLY
|
||||
TbaDXcZvF5ynbZ4WiBm0lOGaufxP/oBXfnfFbObmxC/Jvar5faZ36QkTMN344qHl
|
||||
iliLFMCQI0fPf4IzPz+vQU42ERLq6YYeHRwrOE89b28/Q+hfGBR+bmIP6n4gJNZh
|
||||
JgQ6XNvjsntrC9JIo6zzxF21Hw0tgt9MxS/4ueyplzrxhVAeIS7we8uzt3mHffUn
|
||||
NvLWzYVVQL/wfzLtvLJxBIG+6ZdTAY9BhqEUWvV/AQKBgQD/CXmhiyopXNoJrNgS
|
||||
EAyUr808QhUnuAtvlAv80y5YP64IGQTeA/fJhVWwgvb5vxKMTIMANfB+ucWKleQ5
|
||||
XjALEQAGl0jbX2RyyqQYbYfzMEF+ei/mtviuESdOb2khmHi9yIoaEU+29N16PY9s
|
||||
qAp2qcJqvDXzyrASRxwt5kk5vwKBgQDhWErEsN5MrYPcF5dhZRlNBf92KGkIpEQ7
|
||||
M8sVA15Tetw3OPOJGQvqJt+FlzWf6+wZxCnP6o4GgPIb0/8sow8YXLeII7NaGY2E
|
||||
hfN8vpxyRw985JUCz4sYs7ljR8OMkoQ0mUeYs2uV/L2K4jhrmW9+d2Lw0+QmT1i+
|
||||
SudAmsi8TwKBgHfHv3R7o+WhUlZQ83ooR4BdwQqYDs+ExPo2khrAJHgWEGqFNaAA
|
||||
RRREpyYrnEtXziJOnQgwTS93mKuqEnJPJklMRrLRwsolV0wCmGdQqhUxiNEaGf1F
|
||||
2i4GqGtSMBIzRiH8WcA8eS/4eTy8ROxHUALDYCg5FS3W+DLdawKzsZiJAoGAMql0
|
||||
9c+Fyttfv8WWBRGDpKtqiZgANS8pH94/FBRTypTemZO2POZipVvj+NbL+Y5C4HAX
|
||||
rmTfVVr8E4GP5usp46JEqNjN473G8TpkSXFZHuAW/U8uqRkb/ou5bDagIiR2kJS9
|
||||
YflEgM33lxfQ82/lfxs8JUSeEHbaTr3sS7wA0UUCgYEArTuyBWisr66B1h6z+9KG
|
||||
6aEljrOF3yu+fyKNheT94qq6y7D1oeKZ50WtPnAShdrV9cPl1OUuXKxfc8tIpPvo
|
||||
G1JESPA7XgDXJcHOe/lzpjhUaAEqIorxvcurVgScLFUqkZfJ3GJDtnTSlq2702ld
|
||||
W/QO0g+GTeCU349b5k4SODQ=
|
||||
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDhAap7R9i2M8P8
|
||||
33UBRXi6fFAbGm49dUTVsR+TzHRJMIysWB/gSLtZjZjbHY6/fz6K6Q52OTv1iIOH
|
||||
J2ktnzuewUN/0qxIePA2shm/3/lNjida9XNV716lN8StyBLJBkG7OXjI9OnXilxr
|
||||
0Igu297oRJFxpRodd5OP/6rCeEUwafprPp8siOuXclYP7OKiEdU84fqloV7yaeqA
|
||||
yFO7l/8ltLGIJkpd4kBZ4Zi/LoRK8BGbOGQnUfLTppgsY554ZWwCKdXeX8B0SXrF
|
||||
S6zY2QQebpfur/Rd0ONhJwXZy/o4Wjz0j5AqHDn9A6T3OjvwjH8bL+25xlOOK/qu
|
||||
130f5h5dAgMBAAECggEAd0vF0sUd/kRl5h2n0Hu/7cfZRPV3e3hAfbgCUP92rBNk
|
||||
kj/K7sRBKNLtN0dtltRlGYtFUqM3yg+OBMt9dWXWW26GVjAhje8pFSbKhjO+30K+
|
||||
VPiMJQTbvmdaDPVmGFUL5rMq+gj4LoI6TCNtAMMsZSNtpb5uoS7z+sYICEFyFZ8s
|
||||
WKr3tXNVReZ5MvOFj2EQCZhYenSHCnocJw2dNa6/MaKqItSrVhne0deDhOYTx/IZ
|
||||
e38IiKaSgfWFX8GbINT/yUBMoVNSi0hnqNQnZptvCibmF8bRN7GnHD0OXJETHtXd
|
||||
MGw9v4MpFVbDLG9mPid9K/IwyCDrA2+iNBvQHUixlQKBgQDuoc7W5vrKT44GK+mx
|
||||
gCpfphceVXQTlSPqOw9r1Jwor5J6zIgID4SGpebwPMKTt04QQD04kDpyxE61QTr9
|
||||
fKBLNpe4OBEYmbEcbzjmogH+IjuCIuWDdcZJX+Gk0M7rtFg0uq7+1EtxOUZgLw5I
|
||||
LvDzB70jRfn+u7takx6sgPi7UwKBgQDxYfyWh8RZi4caxH8FlWhq8CaIzbZizs5g
|
||||
g2t4l1zvfHah/kf5+wuIn2Jnwq1MsWJD+ccAH8BmZRYoeThFX0o0FsVIxk4JqxUQ
|
||||
iINN7viE0gkaY3AE7Id5uoMMXr5U7YxQODditTYPu4LLzEz379zuhJMIf9qK0tF7
|
||||
Vrp8V8A5jwKBgCD2rxjWjVw3AxptJHoFh1TxH45sJX2zA2QOxoGRvASOxEA8Uqoy
|
||||
Yo8rCayz5/j5wEnUZeCTY8+IuIqnORvdBFN/dhPXgt0QFfwkjQqm5HmThv7iDSxM
|
||||
r5hhK01WHs9GeUzHYPcIomdAjy0oMuPbwCMCNalSuEbs7eOEIR+ZLULLAoGBAKsH
|
||||
5tUx9aoM9vm8aNQn/QhoiKU+PRDdv9UayTd06GC4K8a0SYOSoaV4aV1jzy8cMKhB
|
||||
fwNTfBwRXBXpbjmZPxaRW9Ao0np/QjmowICj5msV92U/N8wFXCigQuKs7ud2OYlN
|
||||
i9Dg3SFgl1iXtaGnzz8hqJzJGqxqnAtsdE5OTuF5AoGBANlFoxtCTFS5CYYHl8MG
|
||||
XTfXA5hGrw0DlszuUj/uSHlkWbxS8ft+7KH5d9vuF3MI6W1MQeRtWDtSofSLDxnz
|
||||
JYo9A12qVP1suPvHecyNXpOiBEY4t+GTfH1Z0478BAj7kT7WB4ZGsmt16+ug252M
|
||||
y3A9pEIS7Ia3/nftz26s0wex
|
||||
-----END PRIVATE KEY-----
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -73,6 +73,62 @@ namespace Opc.Ua.Fuzzing
|
||||
byte[] certificateDer = applicationCertificate.RawData;
|
||||
WriteTestcase(workPath, "X509Cert", "certificate.der", certificateDer);
|
||||
|
||||
// Expired RSA certificate: NotAfter in the past — exercises validity-window logic.
|
||||
using Certificate expiredCertificate = CertificateBuilder
|
||||
.Create("CN=Fuzzing Test Expired, O=OPC Foundation")
|
||||
.SetNotBefore(DateTime.UtcNow.AddDays(-30))
|
||||
.SetNotAfter(DateTime.UtcNow.AddDays(-1))
|
||||
.AddExtension(
|
||||
new X509SubjectAltNameExtension(
|
||||
"urn:opcfoundation.org:fuzzing:expired",
|
||||
["localhost"]))
|
||||
.SetIssuer(issuerCertificate)
|
||||
.SetRSAKeySize(2048)
|
||||
.CreateForRSA();
|
||||
WriteTestcase(workPath, "X509Cert", "certificate-expired.der", expiredCertificate.RawData);
|
||||
|
||||
// Self-signed RSA certificate: no separate issuer — exercises the
|
||||
// self-signature decoder path that skips chain construction.
|
||||
using Certificate selfSignedCertificate = CertificateBuilder
|
||||
.Create("CN=Fuzzing Test SelfSigned, O=OPC Foundation")
|
||||
.SetNotBefore(DateTime.UtcNow.AddDays(-1))
|
||||
.SetNotAfter(DateTime.UtcNow.AddDays(10))
|
||||
.AddExtension(
|
||||
new X509SubjectAltNameExtension(
|
||||
"urn:opcfoundation.org:fuzzing:selfsigned",
|
||||
["localhost", "127.0.0.1", "::1"]))
|
||||
.SetRSAKeySize(2048)
|
||||
.CreateForRSA();
|
||||
WriteTestcase(workPath, "X509Cert", "certificate-selfsigned.der", selfSignedCertificate.RawData);
|
||||
|
||||
// ECC P-256 application certificate + matching PEM private key.
|
||||
// Exercises the ECDsa decode branches in cert + PEM parsers.
|
||||
// A dedicated ECC issuer is required because CertificateBuilder.CreateForECDsa
|
||||
// signs with the issuer's ECDsa private key — an RSA-only issuer is rejected.
|
||||
using Certificate eccIssuerCertificate = CertificateBuilder
|
||||
.Create("CN=Fuzzing Test ECC Root, O=OPC Foundation")
|
||||
.SetNotBefore(DateTime.UtcNow.AddDays(-1))
|
||||
.SetNotAfter(DateTime.UtcNow.AddDays(30))
|
||||
.SetCAConstraint()
|
||||
.SetECCurve(ECCurve.NamedCurves.nistP256)
|
||||
.CreateForECDsa();
|
||||
|
||||
ICertificateBuilder eccApplicationBuilder = CertificateBuilder
|
||||
.Create("CN=Fuzzing Test ECC, O=OPC Foundation")
|
||||
.SetNotBefore(DateTime.UtcNow.AddDays(-1))
|
||||
.SetNotAfter(DateTime.UtcNow.AddDays(10))
|
||||
.AddExtension(
|
||||
new X509SubjectAltNameExtension(
|
||||
"urn:opcfoundation.org:fuzzing:ecc",
|
||||
["localhost"]));
|
||||
eccApplicationBuilder.SetIssuer(eccIssuerCertificate);
|
||||
|
||||
using Certificate eccApplicationCertificate = eccApplicationBuilder
|
||||
.SetECCurve(ECCurve.NamedCurves.nistP256)
|
||||
.CreateForECDsa();
|
||||
WriteTestcase(workPath, "X509Cert", "certificate-ecc.der", eccApplicationCertificate.RawData);
|
||||
|
||||
// CRL with a single revoked entry (original).
|
||||
var crlBuilder = CrlBuilder
|
||||
.Create(issuerCertificate.SubjectName)
|
||||
.SetThisUpdate(DateTime.UtcNow.AddDays(-1))
|
||||
@@ -83,17 +139,58 @@ namespace Opc.Ua.Fuzzing
|
||||
byte[] crlDer = crl.RawData;
|
||||
WriteTestcase(workPath, "X509CRL", "crl.der", crlDer);
|
||||
|
||||
// CRL with multiple revoked entries (exercises the revoked-list loop in EnsureDecoded).
|
||||
var crlMultiBuilder = CrlBuilder
|
||||
.Create(issuerCertificate.SubjectName)
|
||||
.SetThisUpdate(DateTime.UtcNow.AddDays(-2))
|
||||
.SetNextUpdate(DateTime.UtcNow.AddDays(14))
|
||||
.AddRevokedCertificate(applicationCertificate)
|
||||
.AddRevokedCertificate(expiredCertificate)
|
||||
.AddRevokedCertificate(selfSignedCertificate)
|
||||
.AddCRLExtension(new X509CrlNumberExtension(new BigInteger(42)));
|
||||
IX509CRL crlMulti = crlMultiBuilder.CreateForRSA(issuerCertificate);
|
||||
WriteTestcase(workPath, "X509CRL", "crl-multi-revoked.der", crlMulti.RawData);
|
||||
|
||||
// Empty CRL (no revoked entries) — boundary case for the loop.
|
||||
var crlEmptyBuilder = CrlBuilder
|
||||
.Create(issuerCertificate.SubjectName)
|
||||
.SetThisUpdate(DateTime.UtcNow.AddDays(-1))
|
||||
.SetNextUpdate(DateTime.UtcNow.AddDays(7))
|
||||
.AddCRLExtension(new X509CrlNumberExtension(BigInteger.Zero));
|
||||
IX509CRL crlEmpty = crlEmptyBuilder.CreateForRSA(issuerCertificate);
|
||||
WriteTestcase(workPath, "X509CRL", "crl-empty.der", crlEmpty.RawData);
|
||||
|
||||
// RSA CSR (original).
|
||||
byte[] csrDer = DefaultCertificateFactory.Instance.CreateSigningRequest(
|
||||
applicationCertificate,
|
||||
["localhost"]);
|
||||
WriteTestcase(workPath, "X509CSR", "request.der", csrDer);
|
||||
|
||||
// ECC CSR — exercises the ECDsa-signed PKCS#10 decode branch.
|
||||
byte[] eccCsrDer = DefaultCertificateFactory.Instance.CreateSigningRequest(
|
||||
eccApplicationCertificate,
|
||||
["localhost"]);
|
||||
WriteTestcase(workPath, "X509CSR", "request-ecc.der", eccCsrDer);
|
||||
|
||||
// CSR with multiple SAN entries — exercises the extension-request decode loop.
|
||||
byte[] csrMultiSanDer = DefaultCertificateFactory.Instance.CreateSigningRequest(
|
||||
applicationCertificate,
|
||||
["localhost", "127.0.0.1", "::1", "fuzz.example.com"]);
|
||||
WriteTestcase(workPath, "X509CSR", "request-multi-san.der", csrMultiSanDer);
|
||||
|
||||
byte[] certificatePem = PEMWriter.ExportCertificateAsPEM(applicationCertificate);
|
||||
WriteTestcase(workPath, "PEM", "certificate.pem", certificatePem);
|
||||
|
||||
byte[] privateKeyPem = PEMWriter.ExportPrivateKeyAsPEM(applicationCertificate);
|
||||
WriteTestcase(workPath, "PEM", "private-key.pem", privateKeyPem);
|
||||
|
||||
// ECC PEM cert + key.
|
||||
byte[] eccCertificatePem = PEMWriter.ExportCertificateAsPEM(eccApplicationCertificate);
|
||||
WriteTestcase(workPath, "PEM", "certificate-ecc.pem", eccCertificatePem);
|
||||
|
||||
byte[] eccPrivateKeyPem = PEMWriter.ExportPrivateKeyAsPEM(eccApplicationCertificate);
|
||||
WriteTestcase(workPath, "PEM", "private-key-ecc.pem", eccPrivateKeyPem);
|
||||
|
||||
byte[] subjectAltName = new X509SubjectAltNameExtension(
|
||||
"urn:opcfoundation.org:fuzzing",
|
||||
["localhost", "127.0.0.1"]).RawData;
|
||||
@@ -107,6 +204,16 @@ namespace Opc.Ua.Fuzzing
|
||||
WriteTestcase(workPath, "ASN1", "crl-number.der", crlNumber);
|
||||
WriteTestcase(workPath, "ASN1", "sequence.der", CreateSequenceSeed());
|
||||
|
||||
// Additional ASN.1 boundary seeds — exercise the AsnReader entry points
|
||||
// with structural variants beyond the canonical extension layouts.
|
||||
WriteTestcase(workPath, "ASN1", "nested-sequence.der", CreateNestedSequenceSeed());
|
||||
WriteTestcase(workPath, "ASN1", "large-integer.der", CreateLargeIntegerSeed());
|
||||
WriteTestcase(workPath, "ASN1", "subject-alt-name-many.der",
|
||||
new X509SubjectAltNameExtension(
|
||||
"urn:opcfoundation.org:fuzzing:many",
|
||||
["host-a", "host-b", "host-c", "host-d", "host-e",
|
||||
"127.0.0.1", "::1", "10.0.0.1", "10.0.0.2"]).RawData);
|
||||
|
||||
FuzzableCode.FuzzX509CRLCore(crlDer);
|
||||
FuzzableCode.FuzzX509SubjectAltNameExtensionCore(subjectAltName);
|
||||
FuzzableCode.FuzzX509AuthorityKeyIdentifierExtensionCore(authorityKeyIdentifier);
|
||||
@@ -140,5 +247,30 @@ namespace Opc.Ua.Fuzzing
|
||||
writer.PopSequence();
|
||||
return writer.Encode();
|
||||
}
|
||||
|
||||
private static byte[] CreateNestedSequenceSeed()
|
||||
{
|
||||
var writer = new AsnWriter(AsnEncodingRules.DER);
|
||||
writer.PushSequence();
|
||||
writer.WriteInteger(2);
|
||||
writer.PushSequence();
|
||||
writer.WriteObjectIdentifier(X509SubjectAltNameExtension.SubjectAltName2Oid);
|
||||
writer.PushOctetString();
|
||||
writer.WriteInteger(0x7fffffff);
|
||||
writer.PopOctetString();
|
||||
writer.PopSequence();
|
||||
writer.PopSequence();
|
||||
return writer.Encode();
|
||||
}
|
||||
|
||||
private static byte[] CreateLargeIntegerSeed()
|
||||
{
|
||||
var writer = new AsnWriter(AsnEncodingRules.DER);
|
||||
// 256-bit BigInteger — exercises AsnReader.ReadInteger past the
|
||||
// 32 / 64-bit fast paths into the multi-limb branch.
|
||||
var big = (BigInteger.One << 255) - BigInteger.One;
|
||||
writer.WriteInteger(big);
|
||||
return writer.Encode();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user