Codeunit 1464 CertificateRequest Impl., source in 28
Source242526272829metadata in 28
src/System Application/App/Cryptography Management/src/CertificateRequestImpl.Codeunit.al182 lines, Copyright (c) Microsoft Corporation. MIT
// ------------------------------------------------------------------------------------------------
// 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;
using System;
using System.Text;
using System.Utilities;
codeunit 1464 "CertificateRequest Impl."
{
Access = Internal;
InherentEntitlements = X;
InherentPermissions = X;
var
DotNetRSACryptoServiceProvider: DotNet RSACryptoServiceProvider;
DotNetCertificateRequest: DotNet CertificateRequest;
BeginCertReqTok: Label '-----BEGIN CERTIFICATE REQUEST-----', Locked = true;
EndCertReqTok: Label '-----END CERTIFICATE REQUEST-----', Locked = true;
DepricatedHashAlgorithmsMsg: Label 'In compliance with the Microsoft Secure Hash Algorithm deprecation policy SHA1 and MD5 hash alghoritms have been deprecated.';
[NonDebuggable]
procedure InitializeRSA(KeySize: Integer; IncludePrivateParameters: Boolean; var KeyAsXmlString: Text)
begin
DotNetRSACryptoServiceProvider := DotNetRSACryptoServiceProvider.RSACryptoServiceProvider(KeySize);
DotNetRSACryptoServiceProvider.PersistKeyInCsp(false);
KeyAsXmlString := DotNetRSACryptoServiceProvider.ToXmlString(IncludePrivateParameters);
end;
procedure InitializeRSA(KeySize: Integer; IncludePrivateParameters: Boolean; var KeyAsXmlString: SecretText)
var
[NonDebuggable]
KeyAsXml: Text;
begin
InitializeRSA(KeySize, IncludePrivateParameters, KeyAsXml);
KeyAsXmlString := KeyAsXml;
end;
procedure InitializeCertificateRequestUsingRSA(SubjectName: Text; HashAlgorithm: Enum "Hash Algorithm"; RSASignaturePaddingMode: Enum "RSA Signature Padding")
var
DotNetHashAlgorithmName: DotNet HashAlgorithmName;
DotNetRSASignaturePadding: DotNet RSASignaturePadding;
begin
case RSASignaturePaddingMode of
RSASignaturePaddingMode::Pkcs1:
DotNetRSASignaturePadding := DotNetRSASignaturePadding.Pkcs1();
RSASignaturePaddingMode::Pss:
DotNetRSASignaturePadding := DotNetRSASignaturePadding.Pss();
end;
case HashAlgorithm of
HashAlgorithm::MD5, HashAlgorithm::SHA1:
Error(DepricatedHashAlgorithmsMsg);
HashAlgorithm::SHA256:
DotNetHashAlgorithmName := DotNetHashAlgorithmName.SHA256();
HashAlgorithm::SHA384:
DotNetHashAlgorithmName := DotNetHashAlgorithmName.SHA384();
HashAlgorithm::SHA512:
DotNetHashAlgorithmName := DotNetHashAlgorithmName.SHA512();
end;
DotNetCertificateRequest := DotNetCertificateRequest.CertificateRequest(SubjectName, DotNetRSACryptoServiceProvider, DotNetHashAlgorithmName, DotNetRSASignaturePadding);
end;
procedure AddX509BasicConstraintToCertificateRequest(CertificateAuthority: Boolean; HasPathLengthConstraint: Boolean; PathLengthConstraint: Integer; Critical: Boolean)
var
DotNetX509BasicConstraintsExtension: DotNet X509BasicConstraintsExtension;
begin
DotNetCertificateRequest.CertificateExtensions.Add(
DotNetX509BasicConstraintsExtension.X509BasicConstraintsExtension(
CertificateAuthority, HasPathLengthConstraint, PathLengthConstraint, Critical));
end;
procedure AddX509EnhancedKeyUsageToCertificateRequest(OidValues: List of [Text]; Critical: Boolean)
var
DotNetX509EnhancedKeyUsageExtension: DotNet X509EnhancedKeyUsageExtension;
DotNetOidCollection: DotNet OidCollection;
DotNetOid: DotNet Oid;
Item: Text;
begin
DotNetOidCollection := DotNetOidCollection.OidCollection();
foreach Item in OidValues do
DotNetOidCollection.Add(DotNetOid.Oid(Item));
DotNetCertificateRequest.CertificateExtensions.Add(
DotNetX509EnhancedKeyUsageExtension.X509EnhancedKeyUsageExtension(DotNetOidCollection, Critical));
end;
procedure AddX509KeyUsageToCertificateRequest(X509KeyUsageFlags: Integer; Critical: Boolean)
var
DotNetX509KeyUsageExtension: DotNet X509KeyUsageExtension;
DotNetX509KeyUsageFlags: DotNet X509KeyUsageFlags;
begin
DotNetX509KeyUsageFlags := X509KeyUsageFlags;
DotNetCertificateRequest.CertificateExtensions.Add(
DotNetX509KeyUsageExtension.X509KeyUsageExtension(DotNetX509KeyUsageFlags, Critical));
end;
procedure GetX509CertificateRequestExtensionCount(): Integer
begin
if IsNull(DotNetCertificateRequest.CertificateExtensions) then
exit(0);
exit(DotNetCertificateRequest.CertificateExtensions.Count());
end;
procedure CreateSigningRequest(var SigningRequestPemString: Text)
var
Base64Convert: Codeunit "Base64 Convert";
TempBlob: Codeunit "Temp Blob";
SigningRequestOutStream: OutStream;
SigningRequestInStream: InStream;
Pem: TextBuilder;
B64: Text;
Pos: Integer;
B64Length: Integer;
begin
TempBlob.CreateOutStream(SigningRequestOutStream);
TempBlob.CreateInStream(SigningRequestInStream);
CreateSigningRequest(SigningRequestOutStream);
B64 := Base64Convert.ToBase64(SigningRequestInStream);
Pos := 1;
Pem.AppendLine(BeginCertReqTok);
B64Length := StrLen(B64);
while Pos < B64Length do begin
Pem.AppendLine(CopyStr(B64, Pos, 64));
Pos += 64;
end;
Pem.Append(EndCertReqTok);
SigningRequestPemString := Pem.ToText();
end;
procedure CreateSigningRequest(SigningRequestOutStream: OutStream)
var
DotNetSigningRequest: DotNet Array;
begin
CreateSigningRequest(DotNetSigningRequest);
ArrayToOutStream(DotNetSigningRequest, SigningRequestOutStream);
end;
local procedure CreateSigningRequest(var DotNetSigningRequest: DotNet Array)
begin
DotNetSigningRequest := DotNetCertificateRequest.CreateSigningRequest();
end;
procedure CreateSelfSigned(NotBefore: DateTime; NotAfter: DateTime; X509ContentType: Enum "X509 Content Type"; var CertBase64Value: Text)
var
DotNetNotBefore: DotNet DateTimeOffset;
DotNetNotAfter: DotNet DateTimeOffset;
DotNetX509Certificate2: DotNet X509Certificate2;
DotNetTimeSpan: DotNet TimeSpan;
begin
DotNetTimeSpan := DotNetTimeSpan.TimeSpan(0, 0, 0);
DotNetNotBefore := DotNetNotBefore.DateTimeOffset(NotBefore, DotNetTimeSpan);
DotNetNotAfter := DotNetNotAfter.DateTimeOffset(NotAfter, DotNetTimeSpan);
DotNetX509Certificate2 := DotNetCertificateRequest.CreateSelfSigned(DotNetNotBefore, DotNetNotAfter);
TryExportToBase64String(DotNetX509Certificate2, X509ContentType, CertBase64Value);
end;
local procedure ArrayToOutStream(DotNetBytes: DotNet Array; OutputOutStream: OutStream)
var
DotNetMemoryStream: DotNet MemoryStream;
begin
DotNetMemoryStream := DotNetMemoryStream.MemoryStream(DotNetBytes);
CopyStream(OutputOutStream, DotNetMemoryStream);
end;
[TryFunction]
local procedure TryExportToBase64String(DotNetX509Certificate2: DotNet X509Certificate2; X509ContentType: Enum "X509 Content Type"; var CertBase64Value: Text)
var
DotNetConvert: DotNet Convert;
DotNetX509ContentType: DotNet X509ContentType;
DotNetEnum: DotNet Enum;
begin
DotNetX509ContentType := DotNetEnum.Parse(GetDotNetType(DotNetX509ContentType), Format(X509ContentType));
CertBase64Value := DotNetConvert.ToBase64String(DotNetX509Certificate2.Export(DotNetX509ContentType));
end;
}