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

Commit 8e8d076

Browse files
committed
Merge pull request #2574 from bartonjs/unix_pfx
Add support for PFX files on Unix
2 parents aead23a + 917a4e6 commit 8e8d076

File tree

24 files changed

+655
-182
lines changed

24 files changed

+655
-182
lines changed

src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.NativeCrypto.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,21 @@ internal static partial class NativeCrypto
1212
{
1313
private delegate int NegativeSizeReadMethod<in THandle>(THandle handle, byte[] buf, int cBuf);
1414

15+
[DllImport(Libraries.CryptoInterop)]
16+
internal static extern int BioTell(SafeBioHandle bio);
17+
18+
[DllImport(Libraries.CryptoInterop)]
19+
internal static extern int BioSeek(SafeBioHandle bio, int pos);
20+
1521
[DllImport(Libraries.CryptoInterop)]
1622
private static extern int GetX509Thumbprint(SafeX509Handle x509, byte[] buf, int cBuf);
1723

1824
[DllImport(Libraries.CryptoInterop)]
1925
private static extern int GetX509NameRawBytes(IntPtr x509Name, byte[] buf, int cBuf);
2026

27+
[DllImport(Libraries.CryptoInterop)]
28+
internal static extern SafeX509Handle ReadX509AsDerFromBio(SafeBioHandle bio);
29+
2130
[DllImport(Libraries.CryptoInterop)]
2231
internal static extern IntPtr GetX509NotBefore(SafeX509Handle x509);
2332

src/Common/src/Interop/Unix/libcrypto/Interop.BIO.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ internal static partial class libcrypto
1818
[DllImport(Libraries.LibCrypto)]
1919
internal static extern SafeBioHandle BIO_new(IntPtr type);
2020

21+
[DllImport(Libraries.LibCrypto)]
22+
internal static extern SafeBioHandle BIO_new_file(string filename, string mode);
23+
2124
[DllImport(Libraries.LibCrypto)]
2225
internal static extern IntPtr BIO_s_mem();
2326

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
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.Runtime.InteropServices;
5+
6+
using Microsoft.Win32.SafeHandles;
7+
8+
internal static partial class Interop
9+
{
10+
internal static partial class libcrypto
11+
{
12+
[DllImport(Libraries.LibCrypto)]
13+
internal static extern SafeRsaHandle EVP_PKEY_get1_RSA(SafeEvpPkeyHandle pkey);
14+
}
15+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
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;
5+
using System.Runtime.InteropServices;
6+
7+
internal static partial class Interop
8+
{
9+
internal static partial class libcrypto
10+
{
11+
[DllImport(Libraries.LibCrypto)]
12+
internal static extern void EVP_PKEY_free(IntPtr pkey);
13+
}
14+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
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;
5+
using System.Runtime.InteropServices;
6+
7+
using Microsoft.Win32.SafeHandles;
8+
9+
internal static partial class Interop
10+
{
11+
internal static partial class libcrypto
12+
{
13+
[DllImport(Libraries.LibCrypto)]
14+
internal static unsafe extern SafePkcs12Handle d2i_PKCS12(IntPtr zero, byte** ppin, int len);
15+
16+
[DllImport(Libraries.LibCrypto)]
17+
internal static extern SafePkcs12Handle d2i_PKCS12_bio(SafeBioHandle bio, IntPtr zero);
18+
19+
[DllImport(Libraries.LibCrypto)]
20+
internal static extern void PKCS12_free(IntPtr p12);
21+
22+
[DllImport(Libraries.CryptoInterop, CharSet = CharSet.Ansi)]
23+
[return: MarshalAs(UnmanagedType.Bool)]
24+
internal static extern bool PKCS12_parse(SafePkcs12Handle p12, string pass, out SafeEvpPkeyHandle pkey, out SafeX509Handle cert, out SafeX509StackHandle ca);
25+
}
26+
}

src/Common/src/Interop/Unix/libcrypto/Interop.Rsa.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ internal static partial class libcrypto
2121
[DllImport(Libraries.LibCrypto)]
2222
internal static unsafe extern SafeRsaHandle d2i_RSAPublicKey(IntPtr zero, byte** ppin, int len);
2323

24+
[DllImport(Libraries.LibCrypto)]
25+
[return: MarshalAs(UnmanagedType.Bool)]
26+
internal static extern bool RSA_up_ref(IntPtr rsa);
27+
2428
[DllImport(Libraries.LibCrypto)]
2529
internal static extern void RSA_free(IntPtr rsa);
2630

src/Common/src/Interop/Unix/libcrypto/Interop.d2i.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ internal static partial class libcrypto
1414

1515
internal unsafe delegate int I2DFunc<in THandle>(THandle handle, byte** @out);
1616

17-
internal static unsafe THandle OpenSslD2I<THandle>(D2IFunc<THandle> d2i, byte[] data)
17+
internal static unsafe THandle OpenSslD2I<THandle>(D2IFunc<THandle> d2i, byte[] data, bool checkHandle=true)
1818
where THandle : SafeHandle
1919
{
2020
// The OpenSSL d2i_* functions are set up for cascaded calls, so they increment *ppData while reading.
@@ -27,7 +27,10 @@ internal static unsafe THandle OpenSslD2I<THandle>(D2IFunc<THandle> d2i, byte[]
2727

2828
THandle handle = d2i(IntPtr.Zero, ppData, data.Length);
2929

30-
CheckValidOpenSslHandle(handle);
30+
if (checkHandle)
31+
{
32+
CheckValidOpenSslHandle(handle);
33+
}
3134

3235
return handle;
3336
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
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;
5+
using System.Runtime.InteropServices;
6+
7+
namespace Microsoft.Win32.SafeHandles
8+
{
9+
internal sealed class SafeEvpPkeyHandle : SafeHandle
10+
{
11+
private SafeEvpPkeyHandle() :
12+
base(IntPtr.Zero, ownsHandle: true)
13+
{
14+
}
15+
16+
protected override bool ReleaseHandle()
17+
{
18+
Interop.libcrypto.EVP_PKEY_free(handle);
19+
SetHandle(IntPtr.Zero);
20+
return true;
21+
}
22+
23+
public override bool IsInvalid
24+
{
25+
get { return handle == IntPtr.Zero; }
26+
}
27+
}
28+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
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;
5+
using System.Runtime.InteropServices;
6+
7+
namespace Microsoft.Win32.SafeHandles
8+
{
9+
internal sealed class SafePkcs12Handle : SafeHandle
10+
{
11+
private SafePkcs12Handle() :
12+
base(IntPtr.Zero, ownsHandle: true)
13+
{
14+
}
15+
16+
protected override bool ReleaseHandle()
17+
{
18+
Interop.libcrypto.PKCS12_free(handle);
19+
SetHandle(IntPtr.Zero);
20+
return true;
21+
}
22+
23+
public override bool IsInvalid
24+
{
25+
get { return handle == IntPtr.Zero; }
26+
}
27+
}
28+
}

src/Common/src/Microsoft/Win32/SafeHandles/SafeRsaHandle.Unix.cs

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

44
using System;
5+
using System.Diagnostics;
56
using System.Security;
67
using System.Runtime.InteropServices;
78

@@ -26,5 +27,22 @@ public override bool IsInvalid
2627
{
2728
get { return handle == IntPtr.Zero; }
2829
}
30+
31+
internal static SafeRsaHandle DuplicateHandle(IntPtr handle)
32+
{
33+
Debug.Assert(handle != IntPtr.Zero);
34+
35+
// Reliability: Allocate the SafeHandle before calling RSA_up_ref so
36+
// that we don't lose a tracked reference in low-memory situations.
37+
SafeRsaHandle safeHandle = new SafeRsaHandle();
38+
39+
if (!Interop.libcrypto.RSA_up_ref(handle))
40+
{
41+
throw Interop.libcrypto.CreateOpenSslCryptographicException();
42+
}
43+
44+
safeHandle.SetHandle(handle);
45+
return safeHandle;
46+
}
2947
}
3048
}

0 commit comments

Comments
 (0)