Skip to content

Commit

Permalink
Init RSA PSS SignatureAlgorithm Implementation (#867)
Browse files Browse the repository at this point in the history
#### Summary 
As far as I know, the existing RSACryptoServiceProvider implementation
does not offer the option of specifying the PSS padding. My online
research has also shown that this is not possible either.

Therefore, I would like to add my own implementation of the
"SignatureAlgorithm" interface based on the
"System.Security.Cryptography.RSA" class.
For my use case, only a function that signs the data is sufficient.
However, I think that the interface implementation is more similar to
the styleguid.

#### Work Item(s) 
Fixes #866 

Fixes
[AB#524188](https://dynamicssmb2.visualstudio.com/1fcb79e7-ab07-432a-a3c6-6cf5a88ba4a5/_workitems/edit/524188)
  • Loading branch information
MattiLE authored May 16, 2024
1 parent b298fc4 commit fe02f53
Show file tree
Hide file tree
Showing 9 changed files with 674 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@
},
{
"from": 1473,
"to": 1474
"to": 1476
}
],
"target": "OnPrem",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,19 @@ codeunit 1266 "Cryptography Management"
CryptographyManagementImpl.SignData(DataInStream, SignatureKey, HashAlgorithm, SignatureOutStream);
end;

/// <summary>
/// Computes the hash value of the specified string and signs it.
/// </summary>
/// <param name="InputString">Input string for signing.</param>
/// <param name="XmlString">The private key to use in the hash algorithm.</param>
/// <param name="HashAlgorithm">The available hash algorithms are MD5, SHA1, SHA256, SHA384, and SHA512.</param>
/// <param name="RSASignaturePadding">The padding mode to use for the RSA signature.</param>
/// <param name="SignatureOutStream">The stream to write the signature for the specified string.</param>
procedure SignData(InputString: Text; XmlString: SecretText; HashAlgorithm: Enum "Hash Algorithm"; RSASignaturePadding: Enum "RSA Signature Padding"; SignatureOutStream: OutStream)
begin
CryptographyManagementImpl.SignData(InputString, XmlString, HashAlgorithm, RSASignaturePadding, SignatureOutStream);
end;

/// <summary>
/// Verifies that a digital signature is valid.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,30 @@ codeunit 1279 "Cryptography Management Impl."
SignData(DataInStream, SignatureKey.ToXmlString(), HashAlgorithm, SignatureOutStream);
end;

procedure SignData(InputString: Text; XmlString: SecretText; HashAlgorithm: Enum "Hash Algorithm"; RSASignaturePadding: Enum "RSA Signature Padding"; SignatureOutStream: OutStream)
var
TempBlob: Codeunit "Temp Blob";
DataOutStream: OutStream;
DataInStream: InStream;
begin
if InputString = '' then
exit;
TempBlob.CreateOutStream(DataOutStream, TextEncoding::UTF8);
TempBlob.CreateInStream(DataInStream, TextEncoding::UTF8);
DataOutStream.WriteText(InputString);
SignData(DataInStream, XmlString, HashAlgorithm, SignatureOutStream);
end;

procedure SignData(DataInStream: InStream; XmlString: SecretText; HashAlgorithm: Enum "Hash Algorithm"; RSASignaturePadding: Enum "RSA Signature Padding"; SignatureOutStream: OutStream)
var
RSAImpl: Codeunit "RSA Impl.";
begin
if DataInStream.EOS() then
exit;

RSAImpl.SignData(XmlString, DataInStream, HashAlgorithm, RSASignaturePadding, SignatureOutStream);
end;

procedure VerifyData(InputString: Text; XmlString: SecretText; HashAlgorithm: Enum "Hash Algorithm"; SignatureInStream: InStream): Boolean
var
TempBlob: Codeunit "Temp Blob";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// ------------------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// ------------------------------------------------------------------------------------------------

namespace System.Security.Encryption;

/// <summary>
/// Performs asymmetric encryption and digital signature using the implementation of the RSA class.
/// </summary>
codeunit 1475 "RSA"
{
Access = Public;
InherentEntitlements = X;
InherentPermissions = X;

var
RSAImpl: Codeunit "RSA Impl.";

/// <summary>
/// Initializes a new instance of RSA with the specified key size.
/// </summary>
/// <param name="KeySize">The size of the key in bits.</param>
procedure InitializeRSA(KeySize: Integer)
begin
RSAImpl.InitializeRSA(KeySize);
end;

/// <summary>
/// Creates and returns an XML string containing the key of the current RSA object.
/// </summary>
/// <param name="IncludePrivateParameters">true to include a public and private RSA key; false to include only the public key.</param>
/// <returns>An XML string containing the key of the current RSA object.</returns>
procedure ToSecretXmlString(IncludePrivateParameters: Boolean): SecretText
begin
exit(RSAImpl.ToSecretXmlString(IncludePrivateParameters));
end;

/// <summary>
/// Computes the hash value of the specified data and signs it.
/// </summary>
/// <param name="XmlString">The XML string containing RSA key information.</param>
/// <param name="DataInStream">The input stream to hash and sign.</param>
/// <param name="HashAlgorithm">The hash algorithm to use to create the hash value.</param>
/// <param name="RSASignaturePadding">The padding mode to use for the RSA signature.</param>
/// <param name="SignatureOutStream">The RSA signature stream for the specified data.</param>
procedure SignData(XmlString: SecretText; DataInStream: InStream; HashAlgorithm: Enum "Hash Algorithm"; RSASignaturePadding: Enum "RSA Signature Padding"; SignatureOutStream: OutStream)
begin
RSAImpl.SignData(XmlString, DataInStream, HashAlgorithm, RSASignaturePadding, SignatureOutStream);
end;

/// <summary>
/// Verifies that a digital signature is valid by determining the hash value in the signature using the provided public key and comparing it to the hash value of the provided data.
/// </summary>
/// <param name="XmlString">The XML string containing RSA key information.</param>
/// <param name="DataInStream">The input stream of data that was signed.</param>
/// <param name="HashAlgorithm">The name of the hash algorithm used to create the hash value of the data.</param>
/// <param name="RSASignaturePadding">The padding mode to use for the RSA signature.</param>
/// <param name="SignatureInStream">The stream of signature data to be verified.</param>
/// <returns>True if the signature is valid; otherwise, false.</returns>
procedure VerifyData(XmlString: SecretText; DataInStream: InStream; HashAlgorithm: Enum "Hash Algorithm"; RSASignaturePadding: Enum "RSA Signature Padding"; SignatureInStream: InStream): Boolean
begin
exit(RSAImpl.VerifyData(XmlString, DataInStream, HashAlgorithm, RSASignaturePadding, SignatureInStream));
end;

/// <summary>
/// Encrypts the specified text with the RSA algorithm.
/// </summary>
/// <param name="XmlString">The XML string containing RSA key information.</param>
/// <param name="PlainTextInStream">The input stream to encrypt.</param>
/// <param name="OaepPadding">True to perform RSA encryption using OAEP padding; otherwise, false to use PKCS#1 padding.</param>
/// <param name="EncryptedTextOutStream">The RSA encryption stream for the specified text.</param>
procedure Encrypt(XmlString: SecretText; PlainTextInStream: InStream; OaepPadding: Boolean; EncryptedTextOutStream: OutStream)
begin
RSAImpl.Encrypt(XmlString, PlainTextInStream, OaepPadding, EncryptedTextOutStream);
end;

/// <summary>
/// Decrypts the specified text that was previously encrypted with the RSA algorithm.
/// </summary>
/// <param name="XmlString">The XML string containing RSA key information.</param>
/// <param name="EncryptedTextInStream">The input stream to decrypt.</param>
/// <param name="OaepPadding">true to perform RSA encryption using OAEP padding; otherwise, false to use PKCS#1 padding.</param>
/// <param name="DecryptedTextOutStream">The RSA decryption stream for the specified text.</param>
procedure Decrypt(XmlString: SecretText; EncryptedTextInStream: InStream; OaepPadding: Boolean; DecryptedTextOutStream: OutStream)
begin
RSAImpl.Decrypt(XmlString, EncryptedTextInStream, OaepPadding, DecryptedTextOutStream);
end;
}
Loading

0 comments on commit fe02f53

Please sign in to comment.