1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
//! # git-crypt
//!
//! A Rust implementation of git-crypt for transparent encryption of files in a git repository.
//!
//! ## Features
//!
//! - **Transparent Encryption**: Files are automatically encrypted when committed and decrypted when checked out
//! - **AES-256-GCM Encryption**: Strong, authenticated encryption with built-in tamper detection
//! - **Git Filter Integration**: Uses git's clean/smudge filters for seamless operation
//! - **Key Management**: Export and import symmetric keys for secure sharing
//! - **GPG Support**: Optional GPG integration for team key distribution
//! - **SSH/age Sharing**: Optional age/rage integration for sharing keys with SSH recipients
//! - **Simple CLI**: Easy-to-use command-line interface
//!
//! ## Quick Start
//!
//! ### Installation
//!
//! Install from GitHub:
//! ```bash
//! cargo install --git https://github.com/AprilNEA/git-crypt-rs
//! ```
//!
//! Or build from source:
//! ```bash
//! cargo build --release
//! # Binary will be at target/release/git-crypt
//! ```
//!
//! ### Basic Usage
//!
//! ```bash
//! # Initialize in your git repository
//! git-crypt init
//!
//! # Configure which files to encrypt in .gitattributes
//! echo "*.secret filter=git-crypt diff=git-crypt" >> .gitattributes
//! git add .gitattributes
//! git commit -m "Configure git-crypt"
//!
//! # Add encrypted files (automatically encrypted)
//! echo "my secret data" > test.secret
//! git add test.secret
//! git commit -m "Add encrypted file"
//!
//! # Export key for sharing
//! git-crypt export-key git-crypt-key.bin
//! ```
//!
//! ## How It Works
//!
//! git-crypt uses git's filter system to transparently encrypt and decrypt files:
//!
//! 1. **Clean filter** (encryption): When you `git add` a file, the clean filter encrypts it before storing in the repository
//! 2. **Smudge filter** (decryption): When you `git checkout`, the smudge filter decrypts it in your working directory
//! 3. **Diff filter**: When you `git diff`, it shows that the file is encrypted rather than binary gibberish
//!
//! The encryption key is stored in `.git/git-crypt/keys/default` and is never committed to the repository.
//!
//! ### Data Flow
//!
//! **Encryption (git add):**
//! ```text
//! File content → git add → clean filter → encrypt → store in .git
//! ```
//!
//! **Decryption (git checkout):**
//! ```text
//! Encrypted data in .git → smudge filter → decrypt → working directory
//! ```
//!
//! ## Module Overview
//!
//! - [`crypto`] - Core AES-256-GCM encryption/decryption operations
//! - [`key`] - Key management, storage, export/import
//! - [`git`] - Git filter integration and repository operations
//! - [`gpg`] - Optional GPG support for key sharing (requires `gpg` feature)
//! - [`rage`] - Optional age/rage-based SSH key sharing (requires `ssh` feature)
//! - [`error`] - Error types and unified error handling
//!
//! ## Commands
//!
//! - `init` - Initialize git-crypt in the current repository
//! - `lock` - Lock the repository (remove filters, show encrypted content)
//! - `unlock [--key-file PATH]` - Unlock the repository
//! - `export-key OUTPUT` - Export the symmetric key to a file
//! - `import-key INPUT` - Import a symmetric key from a file
//! - `add-gpg-user GPG_ID` - Grant access to a GPG user (requires `gpg` feature)
//! - `add-ssh-user --ssh-key PATH` - Encrypt the key for an SSH recipient via age/rage (requires `ssh` feature)
//! - `import-age-key --input FILE --identity SSH_KEY` - Decrypt an age/rage key blob with your SSH key (requires `ssh` feature)
//! - `status` - Show status of encrypted files (not yet implemented)
//!
//! ## Examples
//!
//! ### Complete Workflow
//!
//! ```bash
//! # 1. Initialize a git repository
//! git init my-secure-repo
//! cd my-secure-repo
//!
//! # 2. Initialize git-crypt
//! git-crypt init
//!
//! # 3. Configure encryption patterns in .gitattributes
//! cat > .gitattributes << 'EOF'
//! # Encrypt all files in the secrets/ directory
//! secrets/** filter=git-crypt diff=git-crypt
//!
//! # Encrypt specific file types
//! *.key filter=git-crypt diff=git-crypt
//! *.secret filter=git-crypt diff=git-crypt
//!
//! # Encrypt specific config files
//! config/database.yml filter=git-crypt diff=git-crypt
//! .env.production filter=git-crypt diff=git-crypt
//! EOF
//!
//! git add .gitattributes
//! git commit -m "Configure git-crypt"
//!
//! # 4. Add encrypted files
//! mkdir -p secrets
//! echo "AWS_SECRET_KEY=secret123" > secrets/api_keys.txt
//! git add secrets/
//! git commit -m "Add encrypted secrets"
//!
//! # 5. Share access with team members
//! git-crypt export-key team-key.bin
//! # Share team-key.bin securely (password manager, secure channel, etc.)
//! ```
//!
//! ### Unlocking on Another Machine
//!
//! ```bash
//! # Clone the repository
//! git clone <repository-url>
//! cd <repository>
//!
//! # At this point, encrypted files show as encrypted data
//!
//! # Unlock with the shared key
//! git-crypt unlock --key-file team-key.bin
//!
//! # Refresh working directory
//! git checkout HEAD -- .
//!
//! # Now files are decrypted
//! cat secrets/api_keys.txt
//! ```
//!
//! ### Lock/Unlock
//!
//! ```bash
//! # Lock repository (useful before sharing working directory)
//! git-crypt lock
//! # Now all encrypted files show their encrypted content
//!
//! # Unlock again
//! git-crypt unlock
//! git checkout HEAD -- .
//! ```
//!
//! ## Security Considerations
//!
//! ### Threat Model
//!
//! **Protected against:**
//! - Unauthorized access to repository content
//! - Accidental exposure of secrets in public repositories
//! - Historical secret leakage in git history
//!
//! **Not protected against:**
//! - Attacks on the working directory (files are plaintext there)
//! - Compromised git client or filters
//! - Key extraction from `.git` directory
//! - Side-channel attacks
//!
//! ### Best Practices
//!
//! 1. Keep `.git/git-crypt/` directory secure
//! 2. Use restrictive file permissions (automatic on Unix)
//! 3. Never commit key files to the repository
//! 4. Use GPG for team key distribution when possible
//! 5. Rotate keys if compromised
//! 6. Consider full-disk encryption for additional security
//! 7. Share exported keys through secure channels only
//!
//! ## Cryptography Details
//!
//! - **Algorithm**: AES-256-GCM (Galois/Counter Mode)
//! - **Key size**: 256 bits (32 bytes)
//! - **Nonce size**: 96 bits (12 bytes), randomly generated per encryption
//! - **Authentication**: Built into GCM mode (16-byte tag)
//!
//! ### Encrypted File Format
//!
//! ```text
//! [GITCRYPT][12-byte nonce][variable-length ciphertext + 16-byte GCM tag]
//! ```
//!
//! The magic header ensures reliable detection of encrypted data and provides
//! versioning capability for future format changes.
//!
//! ## GPG Support (Optional)
//!
//! To enable GPG support, install system dependencies and build with the `gpg` feature:
//!
//! **macOS:**
//! ```bash
//! brew install nettle gmp
//! cargo install --git https://github.com/AprilNEA/git-crypt-rs --features gpg
//! ```
//!
//! **Ubuntu/Debian:**
//! ```bash
//! sudo apt-get install libnettle-dev libgmp-dev
//! cargo install --git https://github.com/AprilNEA/git-crypt-rs --features gpg
//! ```
//!
//! Then use GPG for key sharing:
//! ```bash
//! git-crypt add-gpg-user user@example.com
//! ```
//!
//! ## SSH/age Support (Optional)
//!
//! Build with the `ssh` feature (which pulls in the `age` dependency) to share repository keys using SSH recipients via age/rage:
//!
//! ```bash
//! cargo install --git https://github.com/AprilNEA/git-crypt-rs --features ssh
//!
//! # Encrypt the repo key for a teammate's SSH public key
//! git-crypt add-ssh-user --ssh-key ~/.ssh/id_ed25519.pub --alias teammate
//!
//! # Teammate imports it with their private key
//! git-crypt import-age-key --input .git/git-crypt/keys/age/teammate.age --identity ~/.ssh/id_ed25519
//! ```
//!
//! ## Compatibility
//!
//! **Not compatible with original git-crypt:**
//! - Different file format (magic header + nonce prepended)
//! - Different key storage location
//! - Different filter commands
//!
//! This is a complete reimplementation focusing on:
//! - Memory safety (Rust)
//! - Modern cryptography practices
//! - Simplicity and maintainability
//! - Optional features (GPG)
//!
//! ## Testing
//!
//! The project has a comprehensive test suite with **63 tests** covering:
//!
//! ### Unit Tests (29 tests)
//!
//! Run all unit tests:
//! ```bash
//! cargo test --lib
//! ```
//!
//! - **Crypto module** ([`crypto`]): Encryption correctness, authentication, edge cases
//! - **Key management** ([`key`]): File operations, permissions, key lifecycle
//!
//! ### Integration Tests (16 tests)
//!
//! Run all integration tests:
//! ```bash
//! cargo test --test integration_test
//! ```
//!
//! Tests complete workflows: initialization, lock/unlock, key export/import, multi-repo isolation.
//!
//! ### Filter Tests (6 tests)
//!
//! Run filter tests:
//! ```bash
//! cargo test --test filter_test
//! ```
//!
//! Tests git filter operations: clean (encrypt), smudge (decrypt), diff.
//!
//! ### Edge Case Tests (12 tests)
//!
//! Run edge case tests:
//! ```bash
//! cargo test --test edge_cases_test
//! ```
//!
//! Tests corner cases: large files (10MB), empty files, binary data, Unicode,
//! corruption detection, concurrency, permissions.
//!
//! ## Running All Tests
//!
//! ```bash
//! # Run all tests
//! cargo test
//!
//! # Run with output
//! cargo test -- --nocapture
//!
//! # Run with backtrace
//! RUST_BACKTRACE=1 cargo test
//!
//! # Run specific test
//! cargo test test_encrypt_decrypt
//! ```
//!
//! ## Test Coverage
//!
//! Generate coverage report (requires cargo-tarpaulin):
//! ```bash
//! cargo install cargo-tarpaulin
//! cargo tarpaulin --out Html
//! ```
//!
//! ## Security Testing
//!
//! Tests verify security properties:
//! - ✅ Authentication (wrong key fails decryption)
//! - ✅ Tamper detection (corrupted data rejected)
//! - ✅ File permissions (0600 on Unix)
//! - ✅ Key isolation (different repos use different keys)
//! - ✅ Nonce uniqueness (no nonce reuse)
// Library exports for testing
// Re-export commonly used types
pub use CryptoKey;
pub use ;
pub use GitRepo;
pub use KeyManager;