RADLib
RADical C++ application framework
RADSecurity.h
Go to the documentation of this file.
1 #ifndef RADSECURITY_H
2 #define RADSECURITY_H
3 
9 #pragma once
10 
11 #include <RADCore/RADCore.h>
12 
13 #include <cstdint>
14 #include <string>
15 #include <vector>
16 
17 namespace RADSecurity {
18 
20  struct CapabilitySet {
22  uint64_t effective = 0;
24  uint64_t permitted = 0;
26  uint64_t inheritable = 0;
28  uint64_t bounding = 0;
29 
31  bool hasEffective(int capabilityNumber) const;
32  };
33 
35  struct SandboxProfile {
37  std::string name;
39  std::vector<std::string> readOnlyPaths;
41  std::vector<std::string> writablePaths;
43  bool allowNetwork = false;
45  bool allowDeviceAccess = false;
46  };
47 
49  class Crypto {
50  public:
52  static std::vector<uint8_t> sha256(const std::vector<uint8_t>& bytes);
54  static std::vector<uint8_t> sha256(const std::string& text);
56  static RADCore::RADResult<std::vector<uint8_t>> sha256File(const std::string& path);
58  static std::string toHex(const std::vector<uint8_t>& bytes);
60  static RADCore::RADResult<std::vector<uint8_t>> fromHex(const std::string& hex);
66  static RADCore::RADResult<std::string> publicKeyFromPrivateKeyPem(const std::string& privateKeyPem);
69  const std::vector<uint8_t>& bytes, const std::string& privateKeyPem);
71  static bool verifySha256(const std::vector<uint8_t>& bytes,
72  const std::vector<uint8_t>& signature, const std::string& publicKeyPem);
75  const std::string& filePath, const std::string& signaturePath, const std::string& privateKeyPem);
77  static bool verifyFileSha256(
78  const std::string& filePath, const std::string& signaturePath, const std::string& publicKeyPem);
80  static RADCore::RADResult<std::string> fileFingerprintSha256(const std::string& path);
81  };
82 
85  const std::string& procStatusPath = "/proc/self/status");
90 
92  enum class LicenseKind {
94  Unknown,
96  Community,
98  Evaluation,
100  Academic,
104  Commercial,
106  Partner,
108  Internal
109  };
110 
112  enum class LicenseStatus {
114  Valid,
116  Missing,
118  ParseError,
120  BadSignature,
126  NotYetValid,
128  Expired,
139  };
140 
142  struct LicensePayload {
144  std::string product;
146  std::string licenseId;
148  std::string licensee;
150  std::string email;
154  std::string issuedAt;
156  std::string expiresAt;
158  std::string validFrom;
160  std::string machineFingerprint;
164  std::string termsId;
168  int seats = 0;
170  std::vector<std::string> features;
171  };
172 
176  std::string requiredIssuerKeyId;
178  std::string product;
182  std::string requiredFeature;
184  std::string machineFingerprint;
188  int64_t nowUnixSeconds = 0;
190  bool allowPortableLicense = false;
192  std::vector<std::string> revokedIssuerKeyIds;
193  };
194 
198  std::string keyId;
200  std::string publicKeyPem;
202  bool revoked = false;
203  };
204 
210  std::string issuerKeyId;
214  std::string message;
215 
217  bool valid() const;
218  };
219 
222  public:
226  static RADCore::RADResult<std::string> publicKeyFingerprint(const std::string& publicKeyPem);
228  static std::string licenseKindToString(LicenseKind kind);
230  static LicenseKind licenseKindFromString(const std::string& text);
232  static std::string licenseStatusToString(LicenseStatus status);
238  static std::string canonicalPayloadJson(const LicensePayload& payload);
241  const LicensePayload& payload,
242  const std::string& privateKeyPem,
243  const std::string& issuerKeyId = {});
246  LicensePayload payload,
247  const std::string& privateKeyPem,
248  const std::string& machineFingerprintOverride = {},
249  const std::string& issuerKeyId = {});
252  const RADCore::RADJsonDocument& document,
253  const std::string& publicKeyPem,
254  const LicenseCheckOptions& options = {});
257  const RADCore::RADJsonDocument& document,
258  const std::vector<TrustedLicenseKey>& trustedKeys,
259  const LicenseCheckOptions& options = {});
262  const std::string& path,
263  const std::string& publicKeyPem,
264  const LicenseCheckOptions& options = {});
267  const std::string& path,
268  const std::vector<TrustedLicenseKey>& trustedKeys,
269  const LicenseCheckOptions& options = {});
272  const std::string& path,
273  const LicensePayload& payload,
274  const std::string& privateKeyPem,
275  const std::string& issuerKeyId = {});
276  };
277 
278 } // namespace RADSecurity
279 
280 #endif
JSON document wrapper around a root RADJsonValue.
Definition: RADCore.h:648
JSON value supporting null, bool, number, string, array, and object.
Definition: RADCore.h:541
Void specialization for success-or-error operations.
Definition: RADCore.h:188
Success-or-error return value for APIs that should not throw.
Definition: RADCore.h:158
Digest and signing primitives backed by OpenSSL.
Definition: RADSecurity.h:49
static RADCore::RADResult< std::string > fileFingerprintSha256(const std::string &path)
Returns a SHA-256 fingerprint for a certificate/key file.
static RADCore::RADResult< std::string > publicKeyFromPrivateKeyPem(const std::string &privateKeyPem)
Extracts the public key PEM from a private key PEM.
static std::string toHex(const std::vector< uint8_t > &bytes)
Returns lowercase hexadecimal text for bytes.
static std::vector< uint8_t > sha256(const std::vector< uint8_t > &bytes)
Computes SHA-256 over bytes.
static bool verifyFileSha256(const std::string &filePath, const std::string &signaturePath, const std::string &publicKeyPem)
Verifies a file signature generated by signFileSha256().
static RADCore::RADResult< std::vector< uint8_t > > signSha256(const std::vector< uint8_t > &bytes, const std::string &privateKeyPem)
Signs bytes using RSA-SHA256 and a private key PEM.
static RADCore::RADResult< std::vector< uint8_t > > sha256File(const std::string &path)
Computes SHA-256 over file contents.
static RADCore::RADResult< std::vector< uint8_t > > fromHex(const std::string &hex)
Parses lowercase or uppercase hexadecimal text.
static RADCore::RADResult< void > signFileSha256(const std::string &filePath, const std::string &signaturePath, const std::string &privateKeyPem)
Signs a file using RSA-SHA256 and writes the signature bytes.
static RADCore::RADResult< std::string > generateRsaPrivateKeyPem(int bits=2048)
Generates an RSA private key in PEM format.
static bool verifySha256(const std::vector< uint8_t > &bytes, const std::vector< uint8_t > &signature, const std::string &publicKeyPem)
Verifies an RSA-SHA256 signature over bytes.
static std::vector< uint8_t > sha256(const std::string &text)
Computes SHA-256 over text bytes.
static RADCore::RADResult< std::vector< uint8_t > > randomBytes(size_t count)
Generates cryptographically secure random bytes.
Offline signed-license utilities for RADLib and RADLib applications.
Definition: RADSecurity.h:221
static RADCore::RADResult< RADCore::RADJsonDocument > createNodeLockedLicense(LicensePayload payload, const std::string &privateKeyPem, const std::string &machineFingerprintOverride={}, const std::string &issuerKeyId={})
Creates a signed license bound to this machine or to machineFingerprintOverride.
static std::string canonicalPayloadJson(const LicensePayload &payload)
Returns canonical JSON bytes used for signing and verification.
static RADCore::RADJsonValue payloadToJson(const LicensePayload &payload)
Serializes the signed payload in canonical form.
static LicenseCheckResult verifySignedLicenseFile(const std::string &path, const std::vector< TrustedLicenseKey > &trustedKeys, const LicenseCheckOptions &options={})
Loads and verifies a signed license file using a trusted issuer key set.
static std::string licenseKindToString(LicenseKind kind)
Converts a license kind to stable text.
static RADCore::RADResult< LicensePayload > payloadFromJson(const RADCore::RADJsonValue &value)
Parses a payload object from JSON.
static RADCore::RADResult< void > writeSignedLicenseFile(const std::string &path, const LicensePayload &payload, const std::string &privateKeyPem, const std::string &issuerKeyId={})
Writes a signed license file.
static LicenseCheckResult verifySignedLicenseFile(const std::string &path, const std::string &publicKeyPem, const LicenseCheckOptions &options={})
Loads and verifies a signed license file.
static LicenseCheckResult verifySignedLicense(const RADCore::RADJsonDocument &document, const std::string &publicKeyPem, const LicenseCheckOptions &options={})
Verifies a signed license document using publicKeyPem.
static RADCore::RADResult< std::string > machineFingerprint()
Returns a privacy-preserving host fingerprint for local license binding.
static LicenseCheckResult verifySignedLicense(const RADCore::RADJsonDocument &document, const std::vector< TrustedLicenseKey > &trustedKeys, const LicenseCheckOptions &options={})
Verifies a signed license document by selecting the trusted key matching key_id.
static RADCore::RADResult< std::string > publicKeyFingerprint(const std::string &publicKeyPem)
Returns a SHA-256 fingerprint for a PEM public key.
static LicenseKind licenseKindFromString(const std::string &text)
Parses stable license kind text.
static RADCore::RADResult< RADCore::RADJsonDocument > createSignedLicense(const LicensePayload &payload, const std::string &privateKeyPem, const std::string &issuerKeyId={})
Creates a signed license JSON document with a hex RSA-SHA256 signature.
static std::string licenseStatusToString(LicenseStatus status)
Converts a license status to stable text.
Definition: RADSecurity.h:17
RADCore::RADJsonValue sandboxProfileToJson(const SandboxProfile &profile)
Serializes a sandbox profile to JSON for review or external launchers.
RADCore::RADResult< CapabilitySet > readCapabilitySet(const std::string &procStatusPath="/proc/self/status")
Reads Linux process capabilities from procStatusPath.
SandboxProfile sandboxProfileFromJson(const RADCore::RADJsonValue &value)
Parses a sandbox profile from JSON.
LicenseKind
License category encoded in signed RADLib/application license files.
Definition: RADSecurity.h:92
@ Partner
Partner, reseller, integrator, or strategic free commercial grant.
@ Community
Community, personal, educational, evaluation, or non-commercial use.
@ Unknown
License kind could not be parsed.
@ Academic
Academic, research, or classroom grant.
@ Internal
Internal Radical Computer Technologies development or testing grant.
@ Commercial
Paid commercial license.
@ Evaluation
Time-limited trial or evaluation grant.
@ SmallBusiness
No-fee commercial use under the small-business thresholds.
LicenseStatus
Result code returned by license verification.
Definition: RADSecurity.h:112
@ NotYetValid
License is not valid yet.
@ LicenseeMismatch
License is validly signed but belongs to another licensee key.
@ Expired
License has expired.
@ Missing
License file was missing or empty.
@ VersionMismatch
License does not allow the requested major version.
@ Valid
License is valid for the supplied check options.
@ RevokedIssuerKey
Signed license references an issuer key that has been revoked.
@ FeatureMissing
License does not grant the requested feature.
@ UnknownIssuerKey
Signed license references an issuer key that is not trusted.
@ MachineMismatch
License is bound to a different machine fingerprint.
@ BadSignature
Signature is absent, malformed, or does not verify.
@ ParseError
License JSON could not be parsed or had missing required fields.
@ ProductMismatch
License product does not match the requested product.
Linux capability state parsed from /proc status fields.
Definition: RADSecurity.h:20
uint64_t inheritable
Inheritable capability mask.
Definition: RADSecurity.h:26
bool hasEffective(int capabilityNumber) const
Returns true when capabilityNumber is present in the effective set.
uint64_t bounding
Bounding capability mask.
Definition: RADSecurity.h:28
uint64_t permitted
Permitted capability mask.
Definition: RADSecurity.h:24
uint64_t effective
Effective capability mask.
Definition: RADSecurity.h:22
Options applied while verifying a signed license.
Definition: RADSecurity.h:174
std::vector< std::string > revokedIssuerKeyIds
Issuer key ids that should be rejected even when their public key is known.
Definition: RADSecurity.h:192
std::string machineFingerprint
Expected machine fingerprint. Empty uses machineFingerprint().
Definition: RADSecurity.h:184
std::string product
Required product id. Empty skips product checking.
Definition: RADSecurity.h:178
std::string requiredFeature
Required feature id. Empty skips feature checking.
Definition: RADSecurity.h:182
bool allowPortableLicense
Whether portable licenses without a machine fingerprint are allowed.
Definition: RADSecurity.h:190
int64_t nowUnixSeconds
Unix time used for validation. Zero uses the current system time.
Definition: RADSecurity.h:188
std::string expectedLicenseePublicKeyFingerprint
Expected licensee/customer public key fingerprint. Empty skips check.
Definition: RADSecurity.h:186
int appMajorVersion
Requested major version. Zero skips version checking.
Definition: RADSecurity.h:180
std::string requiredIssuerKeyId
Required issuer key id. Empty accepts any trusted issuer key id.
Definition: RADSecurity.h:176
Structured result from signed license verification.
Definition: RADSecurity.h:206
std::string message
Human-readable diagnostic suitable for logs.
Definition: RADSecurity.h:214
std::string issuerKeyId
Issuer key id read from the license document when present.
Definition: RADSecurity.h:210
bool valid() const
Returns true when status is LicenseStatus::Valid.
LicenseStatus status
Final status.
Definition: RADSecurity.h:208
LicensePayload payload
Parsed payload when available.
Definition: RADSecurity.h:212
License payload covered by the RSA-SHA256 signature.
Definition: RADSecurity.h:142
std::string product
Product id, such as "RADLib" or an application id.
Definition: RADSecurity.h:144
std::string email
Optional licensee contact email.
Definition: RADSecurity.h:150
std::string machineFingerprint
Optional machine fingerprint binding. Empty means portable.
Definition: RADSecurity.h:160
std::string licenseePublicKeyFingerprint
Optional SHA-256 fingerprint of the licensee/customer public key.
Definition: RADSecurity.h:162
std::string validFrom
Optional ISO date before which the license is not valid.
Definition: RADSecurity.h:158
std::string termsId
Optional commercial terms reference, invoice id, or grant id.
Definition: RADSecurity.h:164
LicenseKind kind
License category.
Definition: RADSecurity.h:152
int seats
Licensed seat count, or 0 when not seat-limited.
Definition: RADSecurity.h:168
std::string expiresAt
Optional ISO date string. Empty means no expiry.
Definition: RADSecurity.h:156
std::string licenseId
Stable unique license id.
Definition: RADSecurity.h:146
std::vector< std::string > features
Feature ids granted by this license.
Definition: RADSecurity.h:170
int maxMajorVersion
Maximum supported application/framework major version, or 0 for any.
Definition: RADSecurity.h:166
std::string issuedAt
ISO date string, usually YYYY-MM-DD.
Definition: RADSecurity.h:154
std::string licensee
Human-readable licensee name.
Definition: RADSecurity.h:148
Declarative sandbox policy for reporting or future launcher integration.
Definition: RADSecurity.h:35
bool allowNetwork
Whether network access is allowed.
Definition: RADSecurity.h:43
std::vector< std::string > writablePaths
Paths allowed for write access.
Definition: RADSecurity.h:41
bool allowDeviceAccess
Whether device node access is allowed.
Definition: RADSecurity.h:45
std::vector< std::string > readOnlyPaths
Paths allowed for read access.
Definition: RADSecurity.h:39
std::string name
Human-readable policy name.
Definition: RADSecurity.h:37
Public issuer key trusted for license verification.
Definition: RADSecurity.h:196
std::string publicKeyPem
PEM-encoded issuer public key.
Definition: RADSecurity.h:200
bool revoked
Whether this key has been explicitly revoked by policy.
Definition: RADSecurity.h:202
std::string keyId
Stable key id stored in the signed license document.
Definition: RADSecurity.h:198