diff --git a/src/Core/Models/Business/BaseLicense.cs b/src/Core/Models/Business/BaseLicense.cs new file mode 100644 index 0000000000..ef04f2813a --- /dev/null +++ b/src/Core/Models/Business/BaseLicense.cs @@ -0,0 +1,56 @@ +using System.Security.Cryptography; +using System.Security.Cryptography.X509Certificates; +using System.Text.Json.Serialization; +using Bit.Core.Enums; + +namespace Bit.Core.Models.Business; + +public abstract class BaseLicense : ILicense +{ + public string LicenseKey { get; set; } + public Guid Id { get; set; } + public string Name { get; set; } + public int Version { get; set; } + public DateTime Issued { get; set; } + public DateTime? Refresh { get; set; } + public DateTime? Expires { get; set; } + public bool Trial { get; set; } + public LicenseType? LicenseType { get; set; } + public string Hash { get; set; } + public string Signature { get; set; } + public string Token { get; set; } + + [JsonIgnore] + public byte[] SignatureBytes => Convert.FromBase64String(Signature); + + public abstract byte[] GetDataBytes(bool forHash = false); + + public byte[] ComputeHash() + { + using (var alg = SHA256.Create()) + { + return alg.ComputeHash(GetDataBytes(true)); + } + } + + public bool VerifySignature(X509Certificate2 certificate) + { + using (var rsa = certificate.GetRSAPublicKey()) + { + return rsa.VerifyData(GetDataBytes(), SignatureBytes, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); + } + } + + public byte[] Sign(X509Certificate2 certificate) + { + if (!certificate.HasPrivateKey) + { + throw new InvalidOperationException("You don't have the private key!"); + } + + using (var rsa = certificate.GetRSAPrivateKey()) + { + return rsa.SignData(GetDataBytes(), HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); + } + } +} diff --git a/src/Core/Models/Business/OrganizationLicense.cs b/src/Core/Models/Business/OrganizationLicense.cs index e8c04b1277..ed0ab67189 100644 --- a/src/Core/Models/Business/OrganizationLicense.cs +++ b/src/Core/Models/Business/OrganizationLicense.cs @@ -1,9 +1,6 @@ using System.Reflection; using System.Security.Claims; -using System.Security.Cryptography; -using System.Security.Cryptography.X509Certificates; using System.Text; -using System.Text.Json.Serialization; using Bit.Core.AdminConsole.Entities; using Bit.Core.Billing.Enums; using Bit.Core.Billing.Licenses.Extensions; @@ -13,7 +10,7 @@ using Bit.Core.Settings; namespace Bit.Core.Models.Business; -public class OrganizationLicense : ILicense +public class OrganizationLicense : BaseLicense { public OrganizationLicense() { @@ -139,10 +136,7 @@ public class OrganizationLicense : ILicense Signature = Convert.ToBase64String(licenseService.SignLicense(this)); } - public string LicenseKey { get; set; } public Guid InstallationId { get; set; } - public Guid Id { get; set; } - public string Name { get; set; } public string BillingEmail { get; set; } public string BusinessName { get; set; } public bool Enabled { get; set; } @@ -165,10 +159,6 @@ public class OrganizationLicense : ILicense public bool SelfHost { get; set; } public bool UsersGetPremium { get; set; } public bool UseCustomPermissions { get; set; } - public int Version { get; set; } - public DateTime Issued { get; set; } - public DateTime? Refresh { get; set; } - public DateTime? Expires { get; set; } public DateTime? ExpirationWithoutGracePeriod { get; set; } public bool UsePasswordManager { get; set; } public bool UseSecretsManager { get; set; } @@ -181,14 +171,8 @@ public class OrganizationLicense : ILicense public bool AllowAdminAccessToAllCollectionItems { get; set; } = true; // - public bool Trial { get; set; } - public LicenseType? LicenseType { get; set; } public bool UseOrganizationDomains { get; set; } public bool UseAdminSponsoredFamilies { get; set; } - public string Hash { get; set; } - public string Signature { get; set; } - public string Token { get; set; } - [JsonIgnore] public byte[] SignatureBytes => Convert.FromBase64String(Signature); /// /// Represents the current version of the license format. Should be updated whenever new fields are added. @@ -202,7 +186,7 @@ public class OrganizationLicense : ILicense get => Version is >= 1 and <= 16; } - public byte[] GetDataBytes(bool forHash = false) + public override byte[] GetDataBytes(bool forHash = false) { string data = null; if (ValidLicenseVersion) @@ -272,14 +256,6 @@ public class OrganizationLicense : ILicense return Encoding.UTF8.GetBytes(data); } - public byte[] ComputeHash() - { - using (var alg = SHA256.Create()) - { - return alg.ComputeHash(GetDataBytes(true)); - } - } - public bool CanUse( IGlobalSettings globalSettings, ILicensingService licensingService, @@ -596,25 +572,4 @@ public class OrganizationLicense : ILicense return valid; } - - public bool VerifySignature(X509Certificate2 certificate) - { - using (var rsa = certificate.GetRSAPublicKey()) - { - return rsa.VerifyData(GetDataBytes(), SignatureBytes, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); - } - } - - public byte[] Sign(X509Certificate2 certificate) - { - if (!certificate.HasPrivateKey) - { - throw new InvalidOperationException("You don't have the private key!"); - } - - using (var rsa = certificate.GetRSAPrivateKey()) - { - return rsa.SignData(GetDataBytes(), HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); - } - } } diff --git a/src/Core/Models/Business/UserLicense.cs b/src/Core/Models/Business/UserLicense.cs index 797aa6692a..ee6376cfd3 100644 --- a/src/Core/Models/Business/UserLicense.cs +++ b/src/Core/Models/Business/UserLicense.cs @@ -1,17 +1,13 @@ using System.Reflection; using System.Security.Claims; -using System.Security.Cryptography; -using System.Security.Cryptography.X509Certificates; using System.Text; -using System.Text.Json.Serialization; using Bit.Core.Billing.Licenses.Extensions; using Bit.Core.Entities; -using Bit.Core.Enums; using Bit.Core.Services; namespace Bit.Core.Models.Business; -public class UserLicense : ILicense +public class UserLicense : BaseLicense { public UserLicense() { } @@ -58,25 +54,11 @@ public class UserLicense : ILicense Signature = Convert.ToBase64String(licenseService.SignLicense(this)); } - public string LicenseKey { get; set; } - public Guid Id { get; set; } - public string Name { get; set; } public string Email { get; set; } public bool Premium { get; set; } public short? MaxStorageGb { get; set; } - public int Version { get; set; } - public DateTime Issued { get; set; } - public DateTime? Refresh { get; set; } - public DateTime? Expires { get; set; } - public bool Trial { get; set; } - public LicenseType? LicenseType { get; set; } - public string Hash { get; set; } - public string Signature { get; set; } - public string Token { get; set; } - [JsonIgnore] - public byte[] SignatureBytes => Convert.FromBase64String(Signature); - public byte[] GetDataBytes(bool forHash = false) + public override byte[] GetDataBytes(bool forHash = false) { string data = null; if (Version == 1) @@ -109,14 +91,6 @@ public class UserLicense : ILicense return Encoding.UTF8.GetBytes(data); } - public byte[] ComputeHash() - { - using (var alg = SHA256.Create()) - { - return alg.ComputeHash(GetDataBytes(true)); - } - } - public bool CanUse(User user, ClaimsPrincipal claimsPrincipal, out string exception) { if (string.IsNullOrWhiteSpace(Token) || claimsPrincipal is null) @@ -236,25 +210,4 @@ public class UserLicense : ILicense user.Premium == Premium && user.Email.Equals(Email, StringComparison.InvariantCultureIgnoreCase); } - - public bool VerifySignature(X509Certificate2 certificate) - { - using (var rsa = certificate.GetRSAPublicKey()) - { - return rsa.VerifyData(GetDataBytes(), SignatureBytes, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); - } - } - - public byte[] Sign(X509Certificate2 certificate) - { - if (!certificate.HasPrivateKey) - { - throw new InvalidOperationException("You don't have the private key!"); - } - - using (var rsa = certificate.GetRSAPrivateKey()) - { - return rsa.SignData(GetDataBytes(), HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); - } - } }