Skip to content
This repository has been archived by the owner on Apr 1, 2024. It is now read-only.

Commit

Permalink
Merge pull request #146 from vithati/users/vithati/changes
Browse files Browse the repository at this point in the history
Changed KeyFormatter and derived classes visibility from internal to …
  • Loading branch information
AArnott authored Oct 5, 2018
2 parents 2dbd047 + 169fa03 commit e5e07ba
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 100 deletions.
2 changes: 1 addition & 1 deletion src/PCLCrypto.Tests/PCLCrypto.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\PCLCrypto\Formatters\*.cs" LinkBase="Formatters" />
<Compile Include="..\PCLCrypto\Formatters\Asn.cs" Link="Formatters\Asn.cs" />
<Compile Include="..\PCLCrypto.Tests.Shared\**\*.cs" LinkBase="Shared" />
</ItemGroup>
<ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion src/PCLCrypto.Tests/Pkcs1KeyFormatterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public void Pkcs1DecodingTest()

// Now load up the tested one.
byte[] pkcs1KeyBlob = Convert.FromBase64String(AsymmetricKeyAlgorithmProviderTests.Helper.PrivateKeyFormatsAndBlobs[Tuple.Create(PCLCrypto.AsymmetricAlgorithm.RsaOaepSha1, CryptographicPrivateKeyBlobType.Pkcs1RsaPrivateKey)]);
RSAParameters homeReadPkcs1 = KeyFormatter.ToPlatformParameters(KeyFormatter.Pkcs1.Read(pkcs1KeyBlob));
RSAParameters homeReadPkcs1 = KeyFormatter.ToPlatformParameters(KeyFormatter.GetFormatter(CryptographicPrivateKeyBlobType.Pkcs1RsaPrivateKey).Read(pkcs1KeyBlob));
#pragma warning restore 0436
Assert.Equal(WinRTCrypto.CryptographicBuffer.EncodeToHexString(rsaCapi.Modulus), WinRTCrypto.CryptographicBuffer.EncodeToHexString(homeReadPkcs1.Modulus));
Assert.Equal(WinRTCrypto.CryptographicBuffer.EncodeToHexString(rsaCapi.Exponent), WinRTCrypto.CryptographicBuffer.EncodeToHexString(homeReadPkcs1.Exponent));
Expand Down
44 changes: 42 additions & 2 deletions src/PCLCrypto/Formatters/CapiKeyFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace PCLCrypto.Formatters
/// Formats keys in the CAPI file format.
/// This is the format used by RSACryptoServiceProvider.ExportCspBlob
/// </summary>
internal class CapiKeyFormatter : KeyFormatter
public class CapiKeyFormatter : KeyFormatter
{
/// <summary>
/// An identifier that the contents of this blob conform to the PUBLICKEYBLOB specification.
Expand Down Expand Up @@ -52,7 +52,7 @@ internal class CapiKeyFormatter : KeyFormatter
/// </summary>
/// <param name="parameters">The parameters.</param>
/// <returns><c>true</c> if CAPI is compatible with these parameters; <c>false</c> otherwise.</returns>
internal static bool IsCapiCompatible(RSAParameters parameters)
public static bool IsCapiCompatible(RSAParameters parameters)
{
Requires.Argument(parameters.Modulus != null, nameof(parameters), "Modulus must not be null.");

Expand All @@ -79,6 +79,46 @@ internal static bool IsCapiCompatible(RSAParameters parameters)
parameters.Modulus.Length == parameters.D?.Length;
}

/// <summary>
/// Tries to add/remove leading zeros as necessary in an attempt to make the parameters CAPI compatible.
/// </summary>
/// <param name="parameters">The parameters.</param>
/// <returns>The modified set of parameters.</returns>
/// <remarks>
/// The original parameters and their buffers are not modified.
/// </remarks>
public static RSAParameters NegotiateSizes(RSAParameters parameters)
{
if (HasPrivateKey(parameters))
{
if (IsCapiCompatible(parameters))
{
// Don't change a thing. Everything is perfect.
return parameters;
}

parameters.Modulus = TrimLeadingZero(parameters.Modulus);
parameters.D = TrimLeadingZero(parameters.D);
int keyLength = Math.Max(parameters.Modulus.Length, parameters.D?.Length ?? 0);
parameters.Modulus = TrimOrPadZeroToLength(parameters.Modulus, keyLength);
parameters.D = TrimOrPadZeroToLength(parameters.D, keyLength);

int halfKeyLength = (keyLength + 1) / 2;
parameters.P = TrimOrPadZeroToLength(parameters.P, halfKeyLength);
parameters.Q = TrimOrPadZeroToLength(parameters.Q, halfKeyLength);
parameters.DP = TrimOrPadZeroToLength(parameters.DP, halfKeyLength);
parameters.DQ = TrimOrPadZeroToLength(parameters.DQ, halfKeyLength);
parameters.InverseQ = TrimOrPadZeroToLength(parameters.InverseQ, halfKeyLength);
}
else
{
parameters.Modulus = TrimLeadingZero(parameters.Modulus);
}

parameters.Exponent = TrimLeadingZero(parameters.Exponent);
return parameters;
}

/// <summary>
/// Throws an exception if the specified RSAParameters cannot be
/// serialized in the CAPI format.
Expand Down
150 changes: 55 additions & 95 deletions src/PCLCrypto/Formatters/KeyFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace PCLCrypto.Formatters
/// <summary>
/// A base class for encoding and decoding RSA keys in various formats.
/// </summary>
internal abstract class KeyFormatter
public abstract class KeyFormatter
{
/// <summary>
/// The PKCS1 key formatter.
Expand Down Expand Up @@ -67,7 +67,7 @@ internal abstract class KeyFormatter
/// </summary>
/// <param name="blobType">Type of the key blob.</param>
/// <returns>An instance of <see cref="KeyFormatter"/></returns>
internal static KeyFormatter GetFormatter(CryptographicPrivateKeyBlobType blobType)
public static KeyFormatter GetFormatter(CryptographicPrivateKeyBlobType blobType)
{
switch (blobType)
{
Expand All @@ -93,7 +93,7 @@ internal static KeyFormatter GetFormatter(CryptographicPrivateKeyBlobType blobTy
/// </summary>
/// <param name="blobType">Type of the key blob.</param>
/// <returns>An instance of <see cref="KeyFormatter"/></returns>
internal static KeyFormatter GetFormatter(CryptographicPublicKeyBlobType blobType)
public static KeyFormatter GetFormatter(CryptographicPublicKeyBlobType blobType)
{
switch (blobType)
{
Expand All @@ -112,12 +112,58 @@ internal static KeyFormatter GetFormatter(CryptographicPublicKeyBlobType blobTyp
}
}

#if !WinRT && (!SILVERLIGHT || WINDOWS_PHONE) // we just want SL5 excluded

/// <summary>
/// Converts the PCLCrypto <see cref="RSAParameters"/> struct to the type
/// offered by the .NET Framework.
/// </summary>
/// <param name="value">The PCLCrypto parameters.</param>
/// <returns>The .NET Framework parameters.</returns>
public static System.Security.Cryptography.RSAParameters ToPlatformParameters(RSAParameters value)
{
return new System.Security.Cryptography.RSAParameters
{
D = value.D,
Q = value.Q,
P = value.P,
DP = value.DP,
DQ = value.DQ,
Exponent = value.Exponent,
InverseQ = value.InverseQ,
Modulus = value.Modulus,
};
}

/// <summary>
/// Converts the .NET Framework <see cref="RSAParameters"/> struct to the type
/// offered by the PCLCrypto library.
/// </summary>
/// <param name="value">The .NET Framework parameters.</param>
/// <returns>The PCLCrypto parameters.</returns>
public static RSAParameters ToPCLParameters(System.Security.Cryptography.RSAParameters value)
{
return new RSAParameters
{
D = value.D,
Q = value.Q,
P = value.P,
DP = value.DP,
DQ = value.DQ,
Exponent = value.Exponent,
InverseQ = value.InverseQ,
Modulus = value.Modulus,
};
}

#endif

/// <summary>
/// Writes a key to the specified stream.
/// </summary>
/// <param name="stream">The stream.</param>
/// <param name="parameters">The parameters.</param>
internal void Write(Stream stream, RSAParameters parameters)
public void Write(Stream stream, RSAParameters parameters)
{
this.Write(stream, parameters, HasPrivateKey(parameters));
}
Expand All @@ -128,7 +174,7 @@ internal void Write(Stream stream, RSAParameters parameters)
/// <param name="stream">The stream.</param>
/// <param name="parameters">The parameters.</param>
/// <param name="includePrivateKey">if set to <c>true</c> the private key will be written as well; otherwise just the public key will be written.</param>
internal void Write(Stream stream, RSAParameters parameters, bool includePrivateKey)
public void Write(Stream stream, RSAParameters parameters, bool includePrivateKey)
{
Requires.NotNull(stream, "stream");
Requires.Argument(HasPrivateKey(parameters) || !includePrivateKey, "parameters", "No private key data included.");
Expand All @@ -146,7 +192,7 @@ internal void Write(Stream stream, RSAParameters parameters, bool includePrivate
/// </summary>
/// <param name="parameters">The parameters.</param>
/// <returns>The buffer with the serialized key.</returns>
internal byte[] Write(RSAParameters parameters)
public byte[] Write(RSAParameters parameters)
{
return this.Write(parameters, HasPrivateKey(parameters));
}
Expand All @@ -157,7 +203,7 @@ internal byte[] Write(RSAParameters parameters)
/// <param name="parameters">The parameters.</param>
/// <param name="includePrivateKey">if set to <c>true</c> the private key will be written as well; otherwise just the public key will be written.</param>
/// <returns>The buffer with the serialized key.</returns>
internal byte[] Write(RSAParameters parameters, bool includePrivateKey)
public byte[] Write(RSAParameters parameters, bool includePrivateKey)
{
var ms = new MemoryStream();
this.Write(ms, parameters, includePrivateKey);
Expand All @@ -169,7 +215,7 @@ internal byte[] Write(RSAParameters parameters, bool includePrivateKey)
/// </summary>
/// <param name="stream">The stream.</param>
/// <returns>The RSA key parameters.</returns>
internal RSAParameters Read(Stream stream)
public RSAParameters Read(Stream stream)
{
var parameters = this.ReadCore(stream);
return TrimLeadingZeros(parameters);
Expand All @@ -180,7 +226,7 @@ internal RSAParameters Read(Stream stream)
/// </summary>
/// <param name="keyBlob">The buffer containing the key data.</param>
/// <returns>The RSA key parameters.</returns>
internal RSAParameters Read(byte[] keyBlob)
public RSAParameters Read(byte[] keyBlob)
{
var ms = new MemoryStream(keyBlob);
return this.Read(ms);
Expand All @@ -200,46 +246,6 @@ protected internal static RSAParameters PublicKeyFilter(RSAParameters value)
};
}

/// <summary>
/// Tries to add/remove leading zeros as necessary in an attempt to make the parameters CAPI compatible.
/// </summary>
/// <param name="parameters">The parameters.</param>
/// <returns>The modified set of parameters.</returns>
/// <remarks>
/// The original parameters and their buffers are not modified.
/// </remarks>
protected internal static RSAParameters NegotiateSizes(RSAParameters parameters)
{
if (HasPrivateKey(parameters))
{
if (CapiKeyFormatter.IsCapiCompatible(parameters))
{
// Don't change a thing. Everything is perfect.
return parameters;
}

parameters.Modulus = TrimLeadingZero(parameters.Modulus);
parameters.D = TrimLeadingZero(parameters.D);
int keyLength = Math.Max(parameters.Modulus.Length, parameters.D?.Length ?? 0);
parameters.Modulus = TrimOrPadZeroToLength(parameters.Modulus, keyLength);
parameters.D = TrimOrPadZeroToLength(parameters.D, keyLength);

int halfKeyLength = (keyLength + 1) / 2;
parameters.P = TrimOrPadZeroToLength(parameters.P, halfKeyLength);
parameters.Q = TrimOrPadZeroToLength(parameters.Q, halfKeyLength);
parameters.DP = TrimOrPadZeroToLength(parameters.DP, halfKeyLength);
parameters.DQ = TrimOrPadZeroToLength(parameters.DQ, halfKeyLength);
parameters.InverseQ = TrimOrPadZeroToLength(parameters.InverseQ, halfKeyLength);
}
else
{
parameters.Modulus = TrimLeadingZero(parameters.Modulus);
}

parameters.Exponent = TrimLeadingZero(parameters.Exponent);
return parameters;
}

/// <summary>
/// Determines whether a set of RSA parameters includes a private key.
/// </summary>
Expand All @@ -250,52 +256,6 @@ protected internal static bool HasPrivateKey(RSAParameters parameters)
return parameters.P != null;
}

#if !WinRT && (!SILVERLIGHT || WINDOWS_PHONE) // we just want SL5 excluded

/// <summary>
/// Converts the PCLCrypto <see cref="RSAParameters"/> struct to the type
/// offered by the .NET Framework.
/// </summary>
/// <param name="value">The PCLCrypto parameters.</param>
/// <returns>The .NET Framework parameters.</returns>
protected internal static System.Security.Cryptography.RSAParameters ToPlatformParameters(RSAParameters value)
{
return new System.Security.Cryptography.RSAParameters
{
D = value.D,
Q = value.Q,
P = value.P,
DP = value.DP,
DQ = value.DQ,
Exponent = value.Exponent,
InverseQ = value.InverseQ,
Modulus = value.Modulus,
};
}

/// <summary>
/// Converts the .NET Framework <see cref="RSAParameters"/> struct to the type
/// offered by the PCLCrypto library.
/// </summary>
/// <param name="value">The .NET Framework parameters.</param>
/// <returns>The PCLCrypto parameters.</returns>
protected internal static RSAParameters ToPCLParameters(System.Security.Cryptography.RSAParameters value)
{
return new RSAParameters
{
D = value.D,
Q = value.Q,
P = value.P,
DP = value.DP,
DQ = value.DQ,
Exponent = value.Exponent,
InverseQ = value.InverseQ,
Modulus = value.Modulus,
};
}

#endif

/// <summary>
/// Checks whether two buffers have equal contents.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ public ICryptographicKey ImportKeyPair(byte[] keyBlob, CryptographicPrivateKeyBl
{
// Try to make it CAPI compatible since it's faster on desktop,
// and the only thing that could possibly work on wp8.
RSAParameters adjustedParameters = KeyFormatter.NegotiateSizes(parameters);
RSAParameters adjustedParameters = CapiKeyFormatter.NegotiateSizes(parameters);
if (CapiKeyFormatter.IsCapiCompatible(adjustedParameters))
{
parameters = adjustedParameters;
Expand Down

0 comments on commit e5e07ba

Please sign in to comment.