Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit 6c43163

Browse files
committed
Merge pull request #2033 from justinvp/x509_chainpal
Avoid unnecessary allocations related to X509ChainElementCollection
2 parents f953d74 + 920c72b commit 6c43163

File tree

5 files changed

+37
-64
lines changed

5 files changed

+37
-64
lines changed

src/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/IChainPal.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
33

44
using System;
5-
using System.Collections.Generic;
65
using System.Security.Cryptography.X509Certificates;
76

87
using Microsoft.Win32.SafeHandles;
@@ -16,7 +15,7 @@ internal interface IChainPal : IDisposable
1615
/// </summary>
1716
bool? Verify(X509VerificationFlags flags, out Exception exception);
1817

19-
IEnumerable<X509ChainElement> ChainElements { get; }
18+
X509ChainElement[] ChainElements { get; }
2019
X509ChainStatus[] ChainStatus { get; }
2120
SafeX509ChainHandle SafeHandle { get; }
2221
}

src/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/OpenSslX509ChainProcessor.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
using System;
2-
using System.Collections.Generic;
1+
// Copyright (c) Microsoft. All rights reserved.
2+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
3+
4+
using System;
35
using System.Security.Cryptography.X509Certificates;
46

57
using Microsoft.Win32.SafeHandles;
@@ -18,7 +20,7 @@ public void Dispose()
1820
return null;
1921
}
2022

21-
public IEnumerable<X509ChainElement> ChainElements
23+
public X509ChainElement[] ChainElements
2224
{
2325
get { throw new NotImplementedException(); }
2426
}

src/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/ChainPal.cs

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,13 @@
22
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
33

44
using System;
5-
using System.Text;
6-
using System.Diagnostics;
7-
using System.Globalization;
8-
using System.Collections.Generic;
95
using System.Runtime.InteropServices;
6+
using System.Security.Cryptography;
7+
using System.Security.Cryptography.X509Certificates;
108

11-
using Internal.NativeCrypto;
12-
using Internal.Cryptography;
139
using Internal.Cryptography.Pal.Native;
1410

15-
using System.Security.Cryptography;
16-
17-
using FILETIME = Internal.Cryptography.Pal.Native.FILETIME;
18-
using SafeX509ChainHandle = Microsoft.Win32.SafeHandles.SafeX509ChainHandle;
19-
using System.Security.Cryptography.X509Certificates;
11+
using Microsoft.Win32.SafeHandles;
2012

2113
namespace Internal.Cryptography.Pal
2214
{
@@ -49,7 +41,7 @@ internal sealed partial class ChainPal : IDisposable, IChainPal
4941
return status.dwError == 0;
5042
}
5143

52-
public IEnumerable<X509ChainElement> ChainElements
44+
public X509ChainElement[] ChainElements
5345
{
5446
get
5547
{
@@ -58,7 +50,7 @@ public IEnumerable<X509ChainElement> ChainElements
5850
CERT_CHAIN_CONTEXT* pCertChainContext = (CERT_CHAIN_CONTEXT*)(_chain.DangerousGetHandle());
5951
CERT_SIMPLE_CHAIN* pCertSimpleChain = pCertChainContext->rgpChain[0];
6052

61-
LowLevelListWithIList<X509ChainElement> chainElements = new LowLevelListWithIList<X509ChainElement>();
53+
X509ChainElement[] chainElements = new X509ChainElement[pCertSimpleChain->cElement];
6254
for (int i = 0; i < pCertSimpleChain->cElement; i++)
6355
{
6456
CERT_CHAIN_ELEMENT* pChainElement = pCertSimpleChain->rgpElement[i];
@@ -68,7 +60,7 @@ public IEnumerable<X509ChainElement> ChainElements
6860
String information = Marshal.PtrToStringUni(pChainElement->pwszExtendedErrorInfo);
6961

7062
X509ChainElement chainElement = new X509ChainElement(certificate, chainElementStatus, information);
71-
chainElements.Add(chainElement);
63+
chainElements[i] = chainElement;
7264
}
7365

7466
GC.KeepAlive(this);

src/System.Security.Cryptography.X509Certificates/src/System/Security/Cryptography/X509Certificates/X509ChainElementCollection.cs

Lines changed: 14 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,26 @@
11
// Copyright (c) Microsoft. All rights reserved.
22
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
33

4-
using System;
5-
using System.IO;
6-
using System.Text;
74
using System.Collections;
85
using System.Diagnostics;
9-
using System.Globalization;
10-
using System.Collections.Generic;
11-
using System.Runtime.InteropServices;
12-
13-
using Internal.Cryptography;
146

157
namespace System.Security.Cryptography.X509Certificates
168
{
179
public sealed class X509ChainElementCollection : ICollection, IEnumerable
1810
{
11+
private readonly X509ChainElement[] _elements;
12+
13+
internal X509ChainElementCollection()
14+
{
15+
_elements = Array.Empty<X509ChainElement>();
16+
}
17+
18+
internal X509ChainElementCollection(X509ChainElement[] chainElements)
19+
{
20+
Debug.Assert(chainElements != null, "chainElements != null");
21+
_elements = chainElements;
22+
}
23+
1924
public int Count
2025
{
2126
get { return _elements.Length; }
@@ -26,7 +31,7 @@ public bool IsSynchronized
2631
get { return false; }
2732
}
2833

29-
public Object SyncRoot
34+
public object SyncRoot
3035
{
3136
get { return this; }
3237
}
@@ -79,21 +84,5 @@ IEnumerator IEnumerable.GetEnumerator()
7984
{
8085
return new X509ChainElementEnumerator(this);
8186
}
82-
83-
internal X509ChainElementCollection()
84-
{
85-
_elements = new X509ChainElement[0];
86-
return;
87-
}
88-
89-
internal X509ChainElementCollection(IEnumerable<X509ChainElement> chainElements)
90-
{
91-
_elements = new LowLevelList<X509ChainElement>(chainElements).ToArray();
92-
return;
93-
}
94-
95-
96-
private X509ChainElement[] _elements;
9787
}
9888
}
99-
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
11
// Copyright (c) Microsoft. All rights reserved.
22
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
33

4-
using System;
5-
using System.IO;
6-
using System.Text;
74
using System.Collections;
8-
using System.Diagnostics;
9-
using System.Globalization;
10-
using System.Runtime.InteropServices;
11-
12-
using Internal.Cryptography;
135

146
namespace System.Security.Cryptography.X509Certificates
157
{
168
public sealed class X509ChainElementEnumerator : IEnumerator
179
{
10+
private readonly X509ChainElementCollection _chainElements;
11+
private int _current;
12+
13+
internal X509ChainElementEnumerator(X509ChainElementCollection chainElements)
14+
{
15+
_chainElements = chainElements;
16+
_current = -1;
17+
}
18+
1819
public X509ChainElement Current
1920
{
2021
get
@@ -23,11 +24,11 @@ public X509ChainElement Current
2324
}
2425
}
2526

26-
Object IEnumerator.Current
27+
object IEnumerator.Current
2728
{
2829
get
2930
{
30-
return _chainElements[_current];
31+
return Current;
3132
}
3233
}
3334

@@ -43,15 +44,5 @@ public void Reset()
4344
{
4445
_current = -1;
4546
}
46-
47-
internal X509ChainElementEnumerator(X509ChainElementCollection chainElements)
48-
{
49-
_chainElements = chainElements;
50-
_current = -1;
51-
}
52-
53-
private X509ChainElementCollection _chainElements;
54-
private int _current;
5547
}
5648
}
57-

0 commit comments

Comments
 (0)