Codeunit 1464 CertificateRequest Impl. in 26

App
System Application
Namespace
System.Security.Encryption

Procedures, 10

Versions171819202122232425262728latest

Source242526272829

Source in 26

src/System Application/App/Cryptography Management/src/CertificateRequestImpl.Codeunit.al180 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;
    begin
        DotNetNotBefore := DotNetNotBefore.DateTimeOffset(NotBefore);
        DotNetNotAfter := DotNetNotBefore.DateTimeOffset(NotAfter);
        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;
}

Procedures, 10

NameParametersReturnsAccessObsolete
InitializeRSA(Integer, Boolean, var Text)public-
InitializeCertificateRequestUsingRSA(Text, Enum Hash Algorithm, Enum RSA Signature Padding)public-
AddX509BasicConstraintToCertificateRequest(Boolean, Boolean, Integer, Boolean)public-
AddX509EnhancedKeyUsageToCertificateRequest(List, Boolean)public-
AddX509KeyUsageToCertificateRequest(Integer, Boolean)public-
GetX509CertificateRequestExtensionCount()Integerpublic-
CreateSigningRequest(var Text)public-
CreateSigningRequest(OutStream)public-
CreateSelfSigned(DateTime, DateTime, Enum X509 Content Type, var Text)public-
InitializeRSA(Integer, Boolean, var SecretText)public-