diff --git a/DigitalData.Core.Security/CryptFactory.cs b/DigitalData.Core.Security/CryptFactory.cs index 009cf2d..87212df 100644 --- a/DigitalData.Core.Security/CryptFactory.cs +++ b/DigitalData.Core.Security/CryptFactory.cs @@ -22,56 +22,5 @@ namespace DigitalData.Core.Security } public bool TryGetRSADecryptor(string key, out IRSADecryptor? decryptor) => _decryptors.TryGetValue(key, out decryptor); - - public static readonly string DefaultEncryptedPrivateKeyFileTag = "enc-private"; - - public static readonly string DefaultPrivateKeyFileTag = "private"; - - public static readonly string DefaultPublicKeyFileTag = "public"; - - public static readonly IEnumerable KeyFileTags = new string[] { DefaultEncryptedPrivateKeyFileTag, DefaultPrivateKeyFileTag, DefaultPublicKeyFileTag }; - - public static readonly string PEMFileExtension = ".pem"; - - private static readonly Lazy> LazyLowerFileTags = new(() => KeyFileTags.Select(tag => tag.ToLower())); - - //TODO: make the validation using regex - public static string DefaultRSAKeyNameFormatter(string issuer, string audience, bool isPrivate = true, Version? passwordVersion = null, string separator = "-_-") - { - void ValidateForbidden(string value, string paramName) - { - if (Path.GetInvalidFileNameChars().Any(value.Contains) || LazyLowerFileTags.Value.Any(tag => value.ToLower().Contains(tag))) - throw new ArgumentException($"RSA decryptor key name creation is forbidden. The {paramName} contains forbidden characters that are not allowed in file naming.", paramName); - } - - static void ValidateSeparator(string value, string paramName, string separator) - { - if (value.Contains(separator)) - throw new ArgumentException($"RSA decryptor key name creation is forbidden. The {paramName} contains separator characters ({separator}) that are not allowed in file naming.", paramName); - } - - ValidateForbidden(issuer, nameof(issuer)); - ValidateForbidden(audience, nameof(audience)); - ValidateForbidden(separator, nameof(separator)); - - ValidateSeparator(issuer, nameof(issuer), separator); - ValidateSeparator(audience, nameof(audience), separator); - - var sb = new StringBuilder(issuer.Length + audience.Length + separator.Length * 2 + 20); - sb.Append(issuer).Append(separator).Append(audience).Append(separator); - - if (passwordVersion is null && isPrivate) - sb.Append(DefaultPrivateKeyFileTag); - else if(isPrivate) - sb.Append(DefaultEncryptedPrivateKeyFileTag).Append(separator).Append(passwordVersion); - else if(passwordVersion is null) - sb.Append(DefaultPublicKeyFileTag); - else - sb.Append(DefaultPublicKeyFileTag).Append(separator).Append(passwordVersion); - - var rsaKey = sb.Append(PEMFileExtension).ToString(); - - return rsaKey; - } } } \ No newline at end of file diff --git a/DigitalData.Core.Security/RSAFactory.cs b/DigitalData.Core.Security/RSAFactory.cs index d50522f..4e920f0 100644 --- a/DigitalData.Core.Security/RSAFactory.cs +++ b/DigitalData.Core.Security/RSAFactory.cs @@ -1,4 +1,5 @@ using System.Security.Cryptography; +using System.Text; namespace DigitalData.Core.Security { @@ -8,6 +9,57 @@ namespace DigitalData.Core.Security public static RSAFactory Static => LazyInstance.Value; + public static readonly string DefaultEncryptedPrivateKeyFileTag = "enc-private"; + + public static readonly string DefaultPrivateKeyFileTag = "private"; + + public static readonly string DefaultPublicKeyFileTag = "public"; + + public static readonly IEnumerable KeyFileTags = new string[] { DefaultEncryptedPrivateKeyFileTag, DefaultPrivateKeyFileTag, DefaultPublicKeyFileTag }; + + public static readonly string PEMFileExtension = ".pem"; + + private static readonly Lazy> LazyLowerFileTags = new(() => KeyFileTags.Select(tag => tag.ToLower())); + + //TODO: make the validation using regex + public static string DefaultRSAKeyNameFormatter(string issuer, string audience, bool isPrivate = true, Version? passwordVersion = null, string separator = "-_-") + { + void ValidateForbidden(string value, string paramName) + { + if (Path.GetInvalidFileNameChars().Any(value.Contains) || LazyLowerFileTags.Value.Any(tag => value.ToLower().Contains(tag))) + throw new ArgumentException($"RSA decryptor key name creation is forbidden. The {paramName} contains forbidden characters that are not allowed in file naming.", paramName); + } + + static void ValidateSeparator(string value, string paramName, string separator) + { + if (value.Contains(separator)) + throw new ArgumentException($"RSA decryptor key name creation is forbidden. The {paramName} contains separator characters ({separator}) that are not allowed in file naming.", paramName); + } + + ValidateForbidden(issuer, nameof(issuer)); + ValidateForbidden(audience, nameof(audience)); + ValidateForbidden(separator, nameof(separator)); + + ValidateSeparator(issuer, nameof(issuer), separator); + ValidateSeparator(audience, nameof(audience), separator); + + var sb = new StringBuilder(issuer.Length + audience.Length + separator.Length * 2 + 20); + sb.Append(issuer).Append(separator).Append(audience).Append(separator); + + if (passwordVersion is null && isPrivate) + sb.Append(DefaultPrivateKeyFileTag); + else if (isPrivate) + sb.Append(DefaultEncryptedPrivateKeyFileTag).Append(separator).Append(passwordVersion); + else if (passwordVersion is null) + sb.Append(DefaultPublicKeyFileTag); + else + sb.Append(DefaultPublicKeyFileTag).Append(separator).Append(passwordVersion); + + var rsaKey = sb.Append(PEMFileExtension).ToString(); + + return rsaKey; + } + public int KeySizeInBits { get; init; } = 2048; public string PbePassword { private get; init; } = Secrets.PBE_PASSWORD;