1
0
mirror of https://github.com/bitwarden/server.git synced 2025-05-22 20:11:04 -05:00

Moved common properties/methods between organization and user licenses to common base class

This commit is contained in:
Conner Turnbull 2025-05-20 13:39:12 -04:00
parent 5eec39c7f6
commit ea2ed551cc
No known key found for this signature in database
3 changed files with 60 additions and 96 deletions

View File

@ -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);
}
}
}

View File

@ -1,9 +1,6 @@
using System.Reflection; using System.Reflection;
using System.Security.Claims; using System.Security.Claims;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text; using System.Text;
using System.Text.Json.Serialization;
using Bit.Core.AdminConsole.Entities; using Bit.Core.AdminConsole.Entities;
using Bit.Core.Billing.Enums; using Bit.Core.Billing.Enums;
using Bit.Core.Billing.Licenses.Extensions; using Bit.Core.Billing.Licenses.Extensions;
@ -13,7 +10,7 @@ using Bit.Core.Settings;
namespace Bit.Core.Models.Business; namespace Bit.Core.Models.Business;
public class OrganizationLicense : ILicense public class OrganizationLicense : BaseLicense
{ {
public OrganizationLicense() public OrganizationLicense()
{ {
@ -139,10 +136,7 @@ public class OrganizationLicense : ILicense
Signature = Convert.ToBase64String(licenseService.SignLicense(this)); Signature = Convert.ToBase64String(licenseService.SignLicense(this));
} }
public string LicenseKey { get; set; }
public Guid InstallationId { get; set; } public Guid InstallationId { get; set; }
public Guid Id { get; set; }
public string Name { get; set; }
public string BillingEmail { get; set; } public string BillingEmail { get; set; }
public string BusinessName { get; set; } public string BusinessName { get; set; }
public bool Enabled { get; set; } public bool Enabled { get; set; }
@ -165,10 +159,6 @@ public class OrganizationLicense : ILicense
public bool SelfHost { get; set; } public bool SelfHost { get; set; }
public bool UsersGetPremium { get; set; } public bool UsersGetPremium { get; set; }
public bool UseCustomPermissions { 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 DateTime? ExpirationWithoutGracePeriod { get; set; }
public bool UsePasswordManager { get; set; } public bool UsePasswordManager { get; set; }
public bool UseSecretsManager { get; set; } public bool UseSecretsManager { get; set; }
@ -181,14 +171,8 @@ public class OrganizationLicense : ILicense
public bool AllowAdminAccessToAllCollectionItems { get; set; } = true; public bool AllowAdminAccessToAllCollectionItems { get; set; } = true;
// //
public bool Trial { get; set; }
public LicenseType? LicenseType { get; set; }
public bool UseOrganizationDomains { get; set; } public bool UseOrganizationDomains { get; set; }
public bool UseAdminSponsoredFamilies { 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);
/// <summary> /// <summary>
/// Represents the current version of the license format. Should be updated whenever new fields are added. /// 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; get => Version is >= 1 and <= 16;
} }
public byte[] GetDataBytes(bool forHash = false) public override byte[] GetDataBytes(bool forHash = false)
{ {
string data = null; string data = null;
if (ValidLicenseVersion) if (ValidLicenseVersion)
@ -272,14 +256,6 @@ public class OrganizationLicense : ILicense
return Encoding.UTF8.GetBytes(data); return Encoding.UTF8.GetBytes(data);
} }
public byte[] ComputeHash()
{
using (var alg = SHA256.Create())
{
return alg.ComputeHash(GetDataBytes(true));
}
}
public bool CanUse( public bool CanUse(
IGlobalSettings globalSettings, IGlobalSettings globalSettings,
ILicensingService licensingService, ILicensingService licensingService,
@ -596,25 +572,4 @@ public class OrganizationLicense : ILicense
return valid; 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);
}
}
} }

View File

@ -1,17 +1,13 @@
using System.Reflection; using System.Reflection;
using System.Security.Claims; using System.Security.Claims;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text; using System.Text;
using System.Text.Json.Serialization;
using Bit.Core.Billing.Licenses.Extensions; using Bit.Core.Billing.Licenses.Extensions;
using Bit.Core.Entities; using Bit.Core.Entities;
using Bit.Core.Enums;
using Bit.Core.Services; using Bit.Core.Services;
namespace Bit.Core.Models.Business; namespace Bit.Core.Models.Business;
public class UserLicense : ILicense public class UserLicense : BaseLicense
{ {
public UserLicense() public UserLicense()
{ } { }
@ -58,25 +54,11 @@ public class UserLicense : ILicense
Signature = Convert.ToBase64String(licenseService.SignLicense(this)); 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 string Email { get; set; }
public bool Premium { get; set; } public bool Premium { get; set; }
public short? MaxStorageGb { 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; string data = null;
if (Version == 1) if (Version == 1)
@ -109,14 +91,6 @@ public class UserLicense : ILicense
return Encoding.UTF8.GetBytes(data); 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) public bool CanUse(User user, ClaimsPrincipal claimsPrincipal, out string exception)
{ {
if (string.IsNullOrWhiteSpace(Token) || claimsPrincipal is null) if (string.IsNullOrWhiteSpace(Token) || claimsPrincipal is null)
@ -236,25 +210,4 @@ public class UserLicense : ILicense
user.Premium == Premium && user.Premium == Premium &&
user.Email.Equals(Email, StringComparison.InvariantCultureIgnoreCase); 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);
}
}
} }