First commit
This commit is contained in:
165
packages/core/security/src/SecurityCore.ts
Normal file
165
packages/core/security/src/SecurityCore.ts
Normal file
@@ -0,0 +1,165 @@
|
||||
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');
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user