SWW13/rust-licverify

โ˜… 0Forks 0RustGitHub โ†—Compare

README

๐Ÿ” licverify

Enterprise-Grade License Verification for Rust

Secure, fast, and reliable license validation with hardware binding and automatic expiry enforcement

Crates.io Documentation License: MIT CI


โœจ Why licverify?

licverify is a Rust client for the go-license license verification system. It provides enterprise-grade license validation with cryptographic signatures, hardware binding, and automatic expiry enforcement, fully compatible with licenses generated by the go-license ecosystem.

๐ŸŽฏ Perfect For:

  • ๐Ÿข Enterprise Software: Mission-critical applications requiring secure licensing
  • ๐Ÿ”ฌ Scientific Tools: Research software with institutional licensing
  • ๐ŸŽฎ Gaming: Game engines and tools with hardware-locked licenses
  • ๐Ÿ’ผ SaaS Applications: Cloud services with node-locked licensing

โšก Security That Matters

Feature Benefit Implementation
๐Ÿ” RSA-SHA256 Cryptographic integrity 2048-bit RSA with SHA-256
๐Ÿ’ป Hardware Binding Device-locked licensing MAC, Disk ID, Hostname
โฐ Auto-Expiry Time-based enforcement Background monitoring
๐Ÿ”„ Format Support Legacy compatibility Binary v2.0+ & JSON v1.x

๐Ÿš€ Quick Start

Add this to your Cargo.toml:

[dependencies]
licverify = "0.1.0"

Usage

๐Ÿ”ฅ Basic License Verification

use licverify::Verifier;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Load your RSA public key
    let public_key_pem = std::fs::read_to_string("public.pem")?;
    let verifier = Verifier::new(&public_key_pem)?;
    
    // Load and verify license
    let license = verifier.load_license("license.lic")?;
    
    match verifier.verify(&license) {
        Ok(()) => {
            println!("โœ… License is valid!");
            println!("๐Ÿ“‹ Customer: {}", license.customer_id);
            println!("๐Ÿ“ฆ Product: {}", license.product_id);
            println!("โฐ Expires: {}", license.expiry_date.format("%Y-%m-%d"));
        }
        Err(e) => {
            eprintln!("โŒ License verification failed: {}", e);
            std::process::exit(1);
        }
    }
    
    Ok(())
}

๐Ÿ–ฅ๏ธ Command Line Interface

# Install from source
git clone https://github.com/luhtfiimanal/rust-licverify
cd rust-licverify
cargo build --release

# Verify a license
./target/release/licverify --public-key public.pem --license license.lic

Output:

License ID: 1
Customer: BMKG
Product: Digitizer
Serial: SN12345
Issue Date: 2025-04-29 07:57:17 UTC
Expiry Date: 2026-04-29 07:57:17 UTC
Features: basic, miniseed, seedlink
Days remaining: 225
โœ… License is valid!

๐Ÿ›ก๏ธ Enterprise Features

๐Ÿ”’ Hardware Binding Verification

Prevent license sharing by binding to specific hardware:

use licverify::{Verifier, HardwareInfo};

let verifier = Verifier::new(&public_key_pem)?;
let license = verifier.load_license("license.lic")?;

// Check hardware binding
match verifier.verify_hardware_binding(&license) {
    Ok(()) => println!("โœ… Hardware binding valid"),
    Err(e) => println!("โŒ Hardware mismatch: {}", e),
}

// Get current hardware info
let hw_info = HardwareInfo::get()?;
println!("๐Ÿ–ฅ๏ธ  MAC Addresses: {:?}", hw_info.mac_addresses);
println!("๐Ÿ’พ Disk IDs: {:?}", hw_info.disk_ids);
println!("๐Ÿท๏ธ  Hostname: {}", hw_info.hostname);

๐Ÿšจ Basic Timer Implementation

use licverify::{Verifier, LicenseError};
use std::time::Duration;
use std::thread;

fn start_license_monitor(verifier: Verifier, license_path: String) {
    thread::spawn(move || {
        loop {
            thread::sleep(Duration::from_secs(3600)); // Check every hour
            
            match verifier.load_license(&license_path) {
                Ok(license) => {
                    if let Err(_) = verifier.verify(&license) {
                        eprintln!"โš ๏ธ  License expired or invalid - terminating application");
                        std::process::exit(1);
                    }
                }
                Err(_) => {
                    eprintln!("โŒ Could not load license - terminating application");
                    std::process::exit(1);
                }
            }
        }
    });
}

๐Ÿ›ก๏ธ Production-Ready License Guard

use licverify::Verifier;
use std::sync::{Arc, atomic::{AtomicBool, Ordering}};
use std::time::Duration;
use std::thread;

pub struct LicenseGuard {
    should_shutdown: Arc<AtomicBool>,
}

impl LicenseGuard {
    pub fn new(verifier: Verifier, license_path: String, check_interval_secs: u64) -> Self {
        let should_shutdown = Arc::new(AtomicBool::new(false));
        let should_shutdown_clone = should_shutdown.clone();
        
        thread::spawn(move || {
            loop {
                thread::sleep(Duration::from_secs(check_interval_secs));
                
                match verifier.load_license(&license_path) {
                    Ok(license) => {
                        match verifier.verify(&license) {
                            Ok(()) => {
                                // Check if license expires within 7 days
                                let days_remaining = license.days_until_expiry();
                                if days_remaining <= 7 {
                                    eprintln!("โš ๏ธ  License expires in {} days!", days_remaining);
                                }
                            }
                            Err(_) => {
                                eprintln!("๐Ÿšจ License expired - initiating graceful shutdown");
                                should_shutdown_clone.store(true, Ordering::Relaxed);
                                return;
                            }
                        }
                    }
                    Err(_) => {
                        eprintln!("โŒ License file error - initiating shutdown");
                        should_shutdown_clone.store(true, Ordering::Relaxed);
                        return;
                    }
                }
            }
        });
        
        Self { should_shutdown }
    }
    
    pub fn should_shutdown(&self) -> bool {
        self.should_shutdown.load(Ordering::Relaxed)
    }
}

// Usage in your application
fn main() {
    let verifier = Verifier::new(&public_key_pem).unwrap();
    let license_guard = LicenseGuard::new(verifier, "license.lic".to_string(), 300); // Check every 5 minutes
    
    // Your application main loop
    loop {
        if license_guard.should_shutdown() {
            println!("๐Ÿ›‘ License expired - shutting down gracefully");
            break;
        }
        
        // Your application logic here
        thread::sleep(Duration::from_secs(1));
    }
}

๐Ÿ—๏ธ Architecture & Compatibility

โœจ Core Features

  • ๐Ÿš€ Cross-Platform: Supports Linux, Windows, and macOS
  • ๐Ÿ” RSA-SHA256: 2048-bit RSA with PKCS#1 v1.5 padding
  • ๐Ÿ’ป Hardware Binding: MAC addresses, disk IDs, and hostname verification
  • ๐Ÿ“ Dual Format: Binary (v2.0+) and JSON (v1.x) license support
  • ๐Ÿ–ฅ๏ธ CLI Interface: Simple command-line verification tool
  • ๐Ÿ“š Library: Embeddable Rust library for applications
  • โฐ Auto-Expiry: Background monitoring and enforcement

๐Ÿ”„ go-license Ecosystem Compatibility

This Rust implementation is fully compatible with the go-license ecosystem:

Component Repository Purpose
๐Ÿ”ง License Generator go-license Create and sign licenses
๐Ÿ Python Client python-licverify Python verification
๐Ÿฆ€ Rust Client rust-licverify (this project) Rust verification

๐Ÿ”„ License Format Support

Format Version Features Status
Binary v2.0+ Full feature set โœ… Supported
JSON v1.x Legacy compatibility โœ… Supported
Signature All RSA-2048 + SHA-256 โœ… Verified

๐ŸŒ go-license Ecosystem

This project is part of the broader go-license ecosystem for cross-platform license management:

All clients can verify licenses generated by the go-license system interchangeably, providing flexibility for multi-language environments.


๐Ÿค Contributing

Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.

Development Setup

# Fork and clone the repository
git clone https://github.com/luhtfiimanal/rust-licverify
cd rust-licverify

# Run tests
cargo test

# Format code
cargo fmt

# Run linter
cargo clippy

# Check for security vulnerabilities
cargo audit

Testing

# Run all tests
cargo test

# Run with coverage
cargo test --all-features

# Run benchmarks
cargo bench

Examples

# Basic usage example
cargo run --example basic_usage

# CLI verification
./target/release/licverify --help

Contributors

luhtfiimanalSWW13

Issues