feat: Add PSR-4 implementation with modern authenticated encryption#2
Open
ralflang wants to merge 5 commits intoFRAMEWORK_6_0from
Open
feat: Add PSR-4 implementation with modern authenticated encryption#2ralflang wants to merge 5 commits intoFRAMEWORK_6_0from
ralflang wants to merge 5 commits intoFRAMEWORK_6_0from
Conversation
- Update phpunit.xml.dist to PHPUnit 11.5 schema - Reorganize tests to test/Unit/ structure - Convert tests to use PHPUnit attributes (#[CoversClass], etc.) - Replace deprecated annotations with modern attributes - Add strict_types declarations to all test files - Update test/bootstrap.php with modern autoloading - Add comprehensive test coverage for encryption/decryption - Update .gitignore for PHPUnit cache and Composer artifacts - Update composer.json: PHP ^8.1 requirement, PHPUnit ^11.5 Test results: - 11 tests, 15 assertions: ✅ ALL PASS - PHP 8.2.30: ✅ PASS - PHP 8.4.18: ✅ PASS - Only 1 deprecation in vendor code (horde/crypt_blowfish) - Zero deprecations in Secret library code
Implement complete PSR-4 architecture with three cipher backends: Cipher Implementations: - SodiumCipher (0x02): XSalsa20-Poly1305 via libsodium (PRIMARY) * 256-bit keys, 192-bit nonces, authenticated encryption * Constant-time operations, recommended for new deployments - AesGcmCipher (0x03): AES-256-GCM via OpenSSL (FALLBACK) * 256-bit keys, 96-bit nonces, AEAD mode * Hardware acceleration (AES-NI), FIPS 140-2 compliant - BlowfishCipher (0x01): Legacy Blowfish adapter (BACKWARD COMPAT) * Wraps Horde_Crypt_Blowfish for old encrypted data * No authenticated encryption, ECB mode, 56-byte key limit Core Components: - CipherInterface: Contract for all cipher implementations - EncryptedData: Immutable value object with format header * Magic header 'HS' + version byte + payload * Base64/Base64URL encoding support * Collision probability: 0.0015% (1/65536) - SecretManager: Main facade with factory methods * Automatic cipher selection (Sodium preferred) * Format detection: magic header vs legacy * Transparent decryption of old Blowfish data * needsReEncryption() helper for gradual migration Exception Hierarchy: - SecretException (base) - InvalidKeyException (key validation errors) - EncryptionException (encryption failures) - DecryptionException (decryption/auth failures) - UnsupportedCipherException (missing extensions) Format Specification: - New format: ['H']['S'][version:1byte][nonce+ciphertext+tag] - Legacy format: [raw Blowfish ciphertext] (no header) - Version 0x02: Sodium (24-byte nonce + ciphertext + 16-byte tag) - Version 0x03: AES-GCM (12-byte nonce + ciphertext + 16-byte tag) - Version 0x01: Blowfish with header (future use) Features: - Automatic cipher negotiation and fallback - Gradual migration path from Blowfish to modern ciphers - Type-safe with PHP 8.1+ readonly properties - Strict types throughout (declare(strict_types=1)) - PSR-4 autoloading Security: - Authenticated encryption prevents tampering - Random nonce generation (cryptographically secure) - Constant-time operations (Sodium) - Key length validation - Empty plaintext protection
Implement extensive test coverage for all PSR-4 components:
Test Files Created:
- EncryptedDataTest.php (24 tests):
* Magic header format validation
* Version byte handling
* Base64/Base64URL encoding/decoding
* Round-trip serialization
* Binary payload support
* All version bytes (0x01-0xFF)
- SodiumCipherTest.php (20 tests):
* XSalsa20-Poly1305 encryption/decryption
* Key validation (32 bytes required)
* Authentication tag verification
* Tampering detection
* Nonce uniqueness
* Binary and Unicode support
* Large data handling
- AesGcmCipherTest.php (17 tests):
* AES-256-GCM authenticated encryption
* Key length validation
* Wrong key detection
* Tampering protection
* Nonce structure (12 bytes)
* Large file support
- BlowfishCipherTest.php (11 tests):
* Legacy Blowfish compatibility
* Key truncation (56-byte limit)
* Empty string handling (PSR-0 compat)
* Horde_Secret integration
* No nonce/tag (ECB mode)
- SecretManagerTest.php (21 tests):
* Automatic cipher selection
* Factory methods (Sodium, AES-GCM, Blowfish)
* Round-trip encryption
* Format detection (header vs legacy)
* needsReEncryption() helper
**Migration & Upgrade Tests:**
* testDecryptLegacyBlowfishData: Decrypt PSR-0 Horde_Secret data
* testMigrationScenarioLegacyToModern: Full Blowfish→Sodium migration
* testMigrationScenarioCrossAlgorithm: AES-GCM→Sodium migration
* testBatchMigrationSimulation: Database migration simulation
* testLazyMigrationPattern: On-demand re-encryption pattern
Key Derivation:
- Added HKDF-based key derivation for variable-length keys
- Ensures 32-byte keys for modern ciphers (Sodium, AES-GCM)
- Preserves original key for Blowfish (legacy compatibility)
- Uses hash_hkdf('sha256') with 'horde-secret-v1' context
Legacy Compatibility:
- Validates legacy ciphertext format (min 8 bytes)
- Graceful fallback to Blowfish for data without header
- Tests verify PSR-0 Horde_Secret interoperability
Test Results:
- 104 tests, 185 assertions
- ✅ ALL PASS
- Only 1 deprecation (vendor horde/crypt_blowfish)
- Zero warnings in Secret library code
- Tested on PHP 8.2 and 8.4
Coverage:
- All cipher implementations
- All exception paths
- Format detection edge cases
- Cross-algorithm compatibility
- Real-world migration scenarios
Update copyright years in PSR-0 implementation and add comprehensive integration tests verifying PSR-0 and PSR-4 can coexist. Changes: - Update copyright to 2026 in lib/Horde/Secret.php and Exception.php - Add documentation to PSR-0 Exception about BC maintenance - Add 7 integration tests verifying interoperability PSR-0 API remains completely unchanged - drop-in compatible upgrade. Test results: 111 tests, 213 assertions, all pass
Add comprehensive documentation for PSR-4 modernization and dual-stack architecture. Changes: - Add README.md with quick start, usage examples, migration guide - Add UPGRADING.md with detailed migration instructions and FAQ - Add doc/changelog.yml with version history - Update .horde.yml to version 3.0.0alpha6 with enhanced description - Update composer.json with keywords and suggest extensions - Remove horde/support dependency (not used in PSR-4) Documentation covers: - Dual-stack architecture (PSR-0 + PSR-4) - Backward compatibility guarantees (100% drop-in) - Migration patterns (lazy, batch, cross-algorithm) - Security considerations (AEAD vs Blowfish ECB) - Cipher selection and availability checks - Error handling and troubleshooting - Performance benchmarking - FAQ and getting help Test status: 111 tests, 213 assertions, all pass
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Modernizes Horde_Secret with dual-stack architecture (PSR-0 + PSR-4).
Key features:
Stats: 1,523 lines implementation, 1,707 lines tests, 831 lines docs.
See README.md and UPGRADING.md for details.