"""Vendor-only offline issuer. Never include this tool or its private key in a customer installer.""" import argparse import base64 from datetime import datetime, timezone import getpass import json from pathlib import Path import sys import uuid sys.path.insert(0,str(Path(__file__).resolve().parents[2])) from cryptography.hazmat.primitives import serialization from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey from monitor_runtime.licensing import canonical, verify_document, timestamp def main(): parser=argparse.ArgumentParser() sub=parser.add_subparsers(dest='command',required=True) keygen=sub.add_parser('keygen') keygen.add_argument('--private-key',type=Path,required=True) keygen.add_argument('--public-key',type=Path,required=True) keygen.add_argument('--dpapi',action='store_true',help='Encrypt private key for current Windows account') issue=sub.add_parser('issue') issue.add_argument('--private-key',type=Path,required=True) issue.add_argument('--request',type=Path,required=True) issue.add_argument('--customer',required=True) issue.add_argument('--expires',help='ISO 8601 time with timezone; omitted means perpetual') issue.add_argument('--output',type=Path,required=True) args=parser.parse_args() if args.command=='keygen': if args.private_key.exists() or args.public_key.exists(): parser.error('Refusing to overwrite existing issuer keys') key=Ed25519PrivateKey.generate() if args.dpapi: from monitor_runtime.windows import protect raw=key.private_bytes(serialization.Encoding.PEM,serialization.PrivateFormat.PKCS8,serialization.NoEncryption()) encoded=b'MONITOR-DPAPI-V1\n'+base64.b64encode(protect(raw)) else: password=getpass.getpass('Private-key password (minimum 12 characters): ') if len(password)<12 or password!=getpass.getpass('Confirm password: '): parser.error('Password too short or confirmation mismatch') encoded=key.private_bytes(serialization.Encoding.PEM,serialization.PrivateFormat.PKCS8, serialization.BestAvailableEncryption(password.encode())) args.private_key.parent.mkdir(parents=True,exist_ok=True) args.public_key.parent.mkdir(parents=True,exist_ok=True) with args.private_key.open('xb') as f:f.write(encoded) with args.public_key.open('xb') as f: f.write(key.public_key().public_bytes(serialization.Encoding.PEM,serialization.PublicFormat.SubjectPublicKeyInfo)) print('Issuer keypair created. Keep the private key offline and backed up.') return raw=args.private_key.read_bytes() if raw.startswith(b'MONITOR-DPAPI-V1\n'): from monitor_runtime.windows import protect raw=protect(base64.b64decode(raw.split(b'\n',1)[1]),decrypt=True) key=serialization.load_pem_private_key(raw,password=None) else: key=serialization.load_pem_private_key(raw,password=getpass.getpass('Private-key password: ').encode()) request=json.loads(args.request.read_text(encoding='utf-8')) if request.get('product')!='monitor' or request.get('schema_version')!=1: parser.error('Unsupported machine request') fingerprint=request.get('fingerprint','') if not fingerprint.startswith('v1:') or len(fingerprint)!=67 or any(c not in '0123456789abcdef' for c in fingerprint[3:]): parser.error('Invalid machine fingerprint') now=datetime.now(timezone.utc) payload={'schema_version':1,'product':'monitor','license_id':str(uuid.uuid4()),'customer':args.customer, 'machine_fingerprint':fingerprint,'issued_at':now.isoformat(), 'expires_at':args.expires} document={'payload':payload,'signature':base64.b64encode(key.sign(canonical(payload))).decode('ascii')} public=key.public_key().public_bytes(serialization.Encoding.PEM,serialization.PublicFormat.SubjectPublicKeyInfo) verify_document(document,public,fingerprint) args.output.parent.mkdir(parents=True,exist_ok=True) with args.output.open('x',encoding='utf-8') as f:json.dump(document,f,ensure_ascii=False,indent=2) print('License signed:',args.output) if __name__=='__main__': main()