165 lines
5.0 KiB
TypeScript
165 lines
5.0 KiB
TypeScript
import { DPoPService } from './DPoPService';
|
|
import { CryptoService } from './CryptoService';
|
|
import { KeyManagementService } from './KeyManagementService';
|
|
import type { SecurityConfig, EncryptionResult, KeyReference } from './types';
|
|
|
|
/**
|
|
* Core Security SDK
|
|
* Provides hardware-backed cryptography, DPoP implementation, and contextual encryption
|
|
*
|
|
* Key Features (per FRD):
|
|
* - F.SC.001: Cryptographic utilities (AES-GCM envelope encryption)
|
|
* - F.SC.002: Hardware-backed key storage (Keychain/StrongBox)
|
|
* - F.SC.003: Certificate Pinning logic
|
|
* - F.SC.004: DPoP proof generation
|
|
* - F.SC.005: Organizational Data Encryption Keys (DEKs) management
|
|
* - F.SC.006: Secure wipe/cryptographic erasure
|
|
* - F.SC.007: Device attestation integration
|
|
*/
|
|
export class SecurityCore {
|
|
private config: SecurityConfig;
|
|
private dpopService: DPoPService;
|
|
private cryptoService: CryptoService;
|
|
private keyManagement: KeyManagementService;
|
|
private initialized = false;
|
|
|
|
constructor(config: SecurityConfig) {
|
|
this.config = config;
|
|
this.dpopService = new DPoPService();
|
|
this.cryptoService = new CryptoService();
|
|
this.keyManagement = new KeyManagementService(config);
|
|
}
|
|
|
|
/**
|
|
* Initialize the Security Core
|
|
* Must be called before any other operations
|
|
*/
|
|
async initialize(): Promise<void> {
|
|
if (this.initialized) return;
|
|
|
|
await this.keyManagement.initialize();
|
|
await this.dpopService.initializeKeyPair();
|
|
|
|
this.initialized = true;
|
|
}
|
|
|
|
/**
|
|
* F.SC.004: Generate DPoP proof for request authentication
|
|
*/
|
|
async signDPoPProof(method: string, uri: string, accessToken?: string): Promise<string> {
|
|
this.ensureInitialized();
|
|
return this.dpopService.signProof(method, uri, accessToken);
|
|
}
|
|
|
|
/**
|
|
* F.SC.001: Encrypt data using organizational DEK (envelope encryption)
|
|
*/
|
|
async encryptForOrganization(data: string, orgId: string): Promise<EncryptionResult> {
|
|
this.ensureInitialized();
|
|
|
|
// Get or create organizational DEK
|
|
const orgKeyRef = await this.keyManagement.getOrganizationalKey(orgId);
|
|
|
|
// Generate random file encryption key
|
|
const fileKey = await this.cryptoService.generateKey();
|
|
|
|
// Encrypt data with file key
|
|
const encryptedData = await this.cryptoService.encrypt(data, fileKey);
|
|
|
|
// Wrap file key with organizational DEK
|
|
const wrappedKey = await this.cryptoService.wrapKey(fileKey, orgKeyRef.keyId);
|
|
|
|
return {
|
|
encryptedData: encryptedData.ciphertext,
|
|
keyReference: {
|
|
keyId: wrappedKey,
|
|
orgId,
|
|
keyType: 'dek',
|
|
createdAt: new Date().toISOString()
|
|
},
|
|
iv: encryptedData.iv,
|
|
authTag: encryptedData.authTag
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Decrypt data using organizational DEK
|
|
*/
|
|
async decryptForOrganization(encryptedData: string, keyReference: KeyReference): Promise<string> {
|
|
this.ensureInitialized();
|
|
|
|
if (!keyReference.orgId) {
|
|
throw new Error('Organization ID required for decryption');
|
|
}
|
|
|
|
// Get organizational DEK
|
|
const orgKeyRef = await this.keyManagement.getOrganizationalKey(keyReference.orgId);
|
|
|
|
// Unwrap file key
|
|
const fileKey = await this.cryptoService.unwrapKey(keyReference.keyId, orgKeyRef.keyId);
|
|
|
|
// Decrypt data
|
|
return this.cryptoService.decrypt(encryptedData, fileKey);
|
|
}
|
|
|
|
/**
|
|
* F.SC.002: Get database master key from secure storage
|
|
*/
|
|
async getDatabaseMasterKey(): Promise<string> {
|
|
this.ensureInitialized();
|
|
return this.keyManagement.getDatabaseMasterKey();
|
|
}
|
|
|
|
/**
|
|
* F.SC.005: Store authentication tokens securely
|
|
*/
|
|
async storeAuthTokens(accessToken: string, refreshToken: string): Promise<void> {
|
|
this.ensureInitialized();
|
|
await this.keyManagement.storeSecureValue('auth.access_token', accessToken);
|
|
await this.keyManagement.storeSecureValue('auth.refresh_token', refreshToken);
|
|
}
|
|
|
|
/**
|
|
* Get stored authentication tokens
|
|
*/
|
|
async getAuthTokens(): Promise<{ accessToken?: string; refreshToken?: string }> {
|
|
this.ensureInitialized();
|
|
|
|
const [accessToken, refreshToken] = await Promise.all([
|
|
this.keyManagement.getSecureValue('auth.access_token'),
|
|
this.keyManagement.getSecureValue('auth.refresh_token')
|
|
]);
|
|
|
|
return { accessToken, refreshToken };
|
|
}
|
|
|
|
/**
|
|
* F.SC.006: Cryptographic erasure - delete organizational keys
|
|
*/
|
|
async performCryptographicErasure(orgId: string): Promise<void> {
|
|
this.ensureInitialized();
|
|
await this.keyManagement.deleteOrganizationalKeys(orgId);
|
|
}
|
|
|
|
/**
|
|
* F.SC.006: Complete secure wipe - delete all keys
|
|
*/
|
|
async performSecureWipe(): Promise<void> {
|
|
this.ensureInitialized();
|
|
await this.keyManagement.secureWipe();
|
|
}
|
|
|
|
/**
|
|
* Sign arbitrary data with identity key
|
|
*/
|
|
async signData(data: string): Promise<string> {
|
|
this.ensureInitialized();
|
|
return this.dpopService.signData(data);
|
|
}
|
|
|
|
private ensureInitialized(): void {
|
|
if (!this.initialized) {
|
|
throw new Error('SecurityCore must be initialized before use');
|
|
}
|
|
}
|
|
} |