-
Notifications
You must be signed in to change notification settings - Fork 4.6k
/
PfxIterationCountTests.CustomAppContextDataLimit.cs
159 lines (130 loc) · 7.31 KB
/
PfxIterationCountTests.CustomAppContextDataLimit.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using Microsoft.DotNet.RemoteExecutor;
using Microsoft.DotNet.XUnitExtensions;
using System.Collections.Generic;
using System.Linq;
using Test.Cryptography;
using Xunit;
namespace System.Security.Cryptography.X509Certificates.Tests
{
[SkipOnPlatform(TestPlatforms.Browser, "Browser doesn't support X.509 certificates")]
public class PfxIterationCountTests_CustomAppContextDataLimit
{
private static readonly Dictionary<string, PfxInfo> s_certificatesDictionary
= PfxIterationCountTests.s_certificates.ToDictionary((c) => c.Name);
// We need to use virtual in a non-abstract class because RemoteExecutor can't work on abstract classes.
internal virtual X509Certificate Import(byte[] blob) => new X509Certificate(blob);
[ConditionalTheory(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))]
[MemberData(memberName: nameof(PfxIterationCountTests.GetCertsWith_IterationCountNotExceedingDefaultLimit_AndNullOrEmptyPassword_MemberData), MemberType = typeof(PfxIterationCountTests))]
public void Import_AppContextDataWithValueMinusTwo_ActsAsDefaultLimit_IterationCountNotExceedingDefaultLimit(string name, bool usesPbes2, byte[] blob, long iterationCount, bool usesRC2)
{
_ = iterationCount;
_ = blob;
if (usesPbes2 && !PfxTests.Pkcs12PBES2Supported)
{
throw new SkipTestException(name + " uses PBES2, which is not supported on this version.");
}
if (usesRC2 && !PlatformSupport.IsRC2Supported)
{
throw new SkipTestException(name + " uses RC2, which is not supported on this platform.");
}
RemoteExecutor.Invoke((certName) =>
{
AppContext.SetData("System.Security.Cryptography.Pkcs12UnspecifiedPasswordIterationLimit", -2);
PfxInfo pfxInfo = s_certificatesDictionary[certName];
X509Certificate cert = Import(pfxInfo.Blob);
Assert.True(cert.Subject == "CN=test" || cert.Subject == "CN=potato");
}, name).Dispose();
}
[ConditionalTheory(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))]
[MemberData(memberName: nameof(PfxIterationCountTests.GetCertsWith_IterationCountExceedingDefaultLimit_MemberData), MemberType = typeof(PfxIterationCountTests))]
public void Import_AppContextDataWithValueMinusTwo_ActsAsDefaultLimit_IterationCountLimitExceeded_Throws(string name, string password, bool usesPbes2, byte[] blob, long iterationCount, bool usesRC2)
{
_ = password;
_ = iterationCount;
_ = blob;
if (usesPbes2 && !PfxTests.Pkcs12PBES2Supported)
{
throw new SkipTestException(name + " uses PBES2, which is not supported on this version.");
}
if (usesRC2 && !PlatformSupport.IsRC2Supported)
{
throw new SkipTestException(name + " uses RC2, which is not supported on this platform.");
}
RemoteExecutor.Invoke((certName) =>
{
AppContext.SetData("System.Security.Cryptography.Pkcs12UnspecifiedPasswordIterationLimit", -2);
PfxInfo pfxInfo = s_certificatesDictionary[certName];
CryptographicException ce = Assert.Throws<CryptographicException>(() => Import(pfxInfo.Blob));
Assert.Contains(PfxIterationCountTests.FwlinkId, ce.Message);
}, name).Dispose();
}
[ConditionalTheory(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))]
[MemberData(memberName: nameof(PfxIterationCountTests.GetCertsWith_IterationCountNotExceedingDefaultLimit_AndNullOrEmptyPassword_MemberData), MemberType = typeof(PfxIterationCountTests))]
public void Import_AppContextDataWithValueZero_IterationCountNotExceedingDefaultLimit_Throws(string name, bool usesPbes2, byte[] blob, long iterationCount, bool usesRC2)
{
_ = iterationCount;
_ = blob;
if (usesPbes2 && !PfxTests.Pkcs12PBES2Supported)
{
throw new SkipTestException(name + " uses PBES2, which is not supported on this version.");
}
if (usesRC2 && !PlatformSupport.IsRC2Supported)
{
throw new SkipTestException(name + " uses RC2, which is not supported on this platform.");
}
RemoteExecutor.Invoke((certName) =>
{
AppContext.SetData("System.Security.Cryptography.Pkcs12UnspecifiedPasswordIterationLimit", 0);
PfxInfo pfxInfo = s_certificatesDictionary[certName];
CryptographicException ce = Assert.Throws<CryptographicException>(() => Import(pfxInfo.Blob));
Assert.Contains(PfxIterationCountTests.FwlinkId, ce.Message);
}, name).Dispose();
}
[ConditionalTheory(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))]
[MemberData(memberName: nameof(PfxIterationCountTests.GetCertsWith_IterationCountExceedingDefaultLimit_MemberData), MemberType = typeof(PfxIterationCountTests))]
public void Import_AppContextDataWithValueMinusOne_IterationCountExceedingDefaultLimit(string name, string password, bool usesPbes2, byte[] blob, long iterationCount, bool usesRC2)
{
_ = password;
_ = blob;
_ = iterationCount;
if (usesPbes2 && !PfxTests.Pkcs12PBES2Supported)
{
throw new SkipTestException(name + " uses PBES2, which is not supported on this version.");
}
if (usesRC2 && !PlatformSupport.IsRC2Supported)
{
throw new SkipTestException(name + " uses RC2, which is not supported on this platform.");
}
RemoteExecutor.Invoke((certName) =>
{
AppContext.SetData("System.Security.Cryptography.Pkcs12UnspecifiedPasswordIterationLimit", -1);
PfxInfo pfxInfo = s_certificatesDictionary[certName];
if (OperatingSystem.IsWindows())
{
// Opting-out with AppContext data value -1 will still give us error because cert is beyond Windows limit.
// But we will get the CryptoThrowHelper+WindowsCryptographicException.
PfxIterationCountTests.VerifyThrowsCryptoExButDoesNotThrowPfxWithoutPassword(() => Import(pfxInfo.Blob));
}
else
{
Assert.NotNull(Import(pfxInfo.Blob));
}
}, name).Dispose();
}
}
public class PfxIterationCountTests_CustomLimit_X509Certificate2 : PfxIterationCountTests_CustomAppContextDataLimit
{
internal override X509Certificate Import(byte[] blob) => new X509Certificate2(blob);
}
public class PfxIterationCountTests_CustomLimit_X509Certificate2Collection : PfxIterationCountTests_CustomAppContextDataLimit
{
internal override X509Certificate Import(byte[] blob)
{
X509Certificate2Collection collection = new X509Certificate2Collection();
collection.Import(blob);
return collection[0];
}
}
}