mirror of
https://github.com/sbrow/envr.git
synced 2026-06-27 18:48:33 -04:00
feat: Added age-ffi.
This commit is contained in:
194
zig-vendor/age-ffi/zig/example.zig
Normal file
194
zig-vendor/age-ffi/zig/example.zig
Normal file
@@ -0,0 +1,194 @@
|
||||
//! Example usage of the age-ffi Zig bindings
|
||||
//!
|
||||
//! This file demonstrates various encryption/decryption operations using the age library.
|
||||
|
||||
const std = @import("std");
|
||||
const age = @import("age.zig");
|
||||
|
||||
pub fn main(init: std.process.Init) !void {
|
||||
const gpa = init.gpa;
|
||||
const io = init.io;
|
||||
|
||||
// Set up unbuffered stdout for Zig 0.15+ (simpler for examples)
|
||||
// var stdout_writer = std.fs.File.stdout().writer(&.{});
|
||||
var stdout_writer = std.Io.File.stdout().writer(io, &.{});
|
||||
const stdout = &stdout_writer.interface;
|
||||
|
||||
try stdout.print("age-ffi Zig Bindings Example\n", .{});
|
||||
try stdout.print("============================\n\n", .{});
|
||||
|
||||
// Print version information
|
||||
try stdout.print("Library version: {s}\n", .{age.getVersion()});
|
||||
try stdout.print("Age library version: {s}\n\n", .{age.getLibVersion()});
|
||||
|
||||
// Example 1: Generate a keypair
|
||||
try stdout.print("Example 1: Generating a keypair\n", .{});
|
||||
try stdout.print("--------------------------------\n", .{});
|
||||
|
||||
var keypair = try age.generateKeypair();
|
||||
defer keypair.deinit();
|
||||
|
||||
try stdout.print("Public key: {s}\n", .{keypair.getPublicKey()});
|
||||
try stdout.print("Private key: {s}\n\n", .{keypair.getPrivateKey()});
|
||||
try stdout.flush();
|
||||
|
||||
// Example 2: Simple encryption and decryption
|
||||
try stdout.print("Example 2: Simple encryption/decryption\n", .{});
|
||||
try stdout.print("---------------------------------------\n", .{});
|
||||
|
||||
const plaintext = "Hello, World! This is a secret message.";
|
||||
try stdout.print("Original: {s}\n", .{plaintext});
|
||||
|
||||
// Encrypt
|
||||
var encrypted = try age.encrypt(plaintext, keypair.getPublicKey());
|
||||
defer encrypted.deinit();
|
||||
|
||||
try stdout.print("Encrypted: {} bytes\n", .{encrypted.buffer.len});
|
||||
|
||||
// Decrypt
|
||||
var decrypted = try age.decrypt(encrypted.toSlice(), keypair.getPrivateKey());
|
||||
defer decrypted.deinit();
|
||||
|
||||
try stdout.print("Decrypted: {s}\n\n", .{decrypted.toSlice()});
|
||||
try stdout.flush();
|
||||
|
||||
// Example 3: ASCII armor
|
||||
try stdout.print("Example 3: ASCII armor encryption\n", .{});
|
||||
try stdout.print("----------------------------------\n", .{});
|
||||
|
||||
var armored = try age.encryptArmor("This message will be ASCII armored.", keypair.getPublicKey());
|
||||
defer armored.deinit();
|
||||
|
||||
try stdout.print("Encrypted with ASCII armor: {} bytes\n", .{armored.buffer.len});
|
||||
|
||||
// Decrypt armored message
|
||||
var decrypted_armored = try age.decrypt(armored.toSlice(), keypair.getPrivateKey());
|
||||
defer decrypted_armored.deinit();
|
||||
|
||||
try stdout.print("Decrypted successfully: {s}\n\n", .{decrypted_armored.toSlice()});
|
||||
try stdout.flush();
|
||||
|
||||
// Example 4: Passphrase-based encryption
|
||||
try stdout.print("Example 4: Passphrase encryption\n", .{});
|
||||
try stdout.print("---------------------------------\n", .{});
|
||||
|
||||
const passphrase = "super-secret-passphrase";
|
||||
const secret_data = "Encrypted with a passphrase!";
|
||||
|
||||
// Encrypt without armor (armor with passphrase has decryption issues in upstream library)
|
||||
var pass_encrypted = try age.encryptPassphrase(secret_data, passphrase, false);
|
||||
defer pass_encrypted.deinit();
|
||||
|
||||
try stdout.print("Passphrase-encrypted: {} bytes\n", .{pass_encrypted.buffer.len});
|
||||
|
||||
var pass_decrypted = try age.decryptPassphrase(pass_encrypted.toSlice(), passphrase);
|
||||
defer pass_decrypted.deinit();
|
||||
|
||||
try stdout.print("Decrypted: {s}\n\n", .{pass_decrypted.toSlice()});
|
||||
try stdout.flush();
|
||||
|
||||
// Example 5: Multiple recipients
|
||||
try stdout.print("Example 5: Multiple recipients\n", .{});
|
||||
try stdout.print("-------------------------------\n", .{});
|
||||
|
||||
// Generate a second keypair
|
||||
var keypair2 = try age.generateKeypair();
|
||||
defer keypair2.deinit();
|
||||
|
||||
try stdout.print("Recipient 1: {s}\n", .{keypair.getPublicKey()});
|
||||
try stdout.print("Recipient 2: {s}\n", .{keypair2.getPublicKey()});
|
||||
|
||||
// Create array of recipients
|
||||
const recipients = [_][:0]const u8{
|
||||
keypair.getPublicKey(),
|
||||
keypair2.getPublicKey(),
|
||||
};
|
||||
|
||||
const multi_plaintext = "This can be decrypted by either recipient!";
|
||||
var multi_encrypted = try age.encryptMulti(multi_plaintext, &recipients, false);
|
||||
defer multi_encrypted.deinit();
|
||||
|
||||
try stdout.print("Encrypted for both recipients ({} bytes)\n", .{multi_encrypted.buffer.len});
|
||||
|
||||
// Decrypt with first identity
|
||||
var multi_decrypted1 = try age.decrypt(multi_encrypted.toSlice(), keypair.getPrivateKey());
|
||||
defer multi_decrypted1.deinit();
|
||||
|
||||
try stdout.print("Decrypted with key 1: {s}\n", .{multi_decrypted1.toSlice()});
|
||||
|
||||
// Decrypt with second identity
|
||||
var multi_decrypted2 = try age.decrypt(multi_encrypted.toSlice(), keypair2.getPrivateKey());
|
||||
defer multi_decrypted2.deinit();
|
||||
|
||||
try stdout.print("Decrypted with key 2: {s}\n\n", .{multi_decrypted2.toSlice()});
|
||||
|
||||
try stdout.flush();
|
||||
// Example 6: File operations
|
||||
try stdout.print("Example 6: File encryption/decryption\n", .{});
|
||||
try stdout.print("--------------------------------------\n", .{});
|
||||
|
||||
const file_data = "This will be written to an encrypted file.";
|
||||
const encrypted_file = "/tmp/test.age";
|
||||
|
||||
// Encrypt to file (non-armored)
|
||||
try age.encryptToFile(file_data, keypair.getPublicKey(), encrypted_file);
|
||||
try stdout.print("Encrypted to file: {s}\n", .{encrypted_file});
|
||||
|
||||
// Decrypt from file
|
||||
var file_decrypted = try age.decryptFileWithIdentity(encrypted_file, keypair.getPrivateKey());
|
||||
defer file_decrypted.deinit();
|
||||
|
||||
try stdout.print("Decrypted from file: {s}\n\n", .{file_decrypted.toSlice()});
|
||||
|
||||
try stdout.flush();
|
||||
// Example 7: Validation
|
||||
try stdout.print("Example 7: Key validation\n", .{});
|
||||
try stdout.print("--------------------------\n", .{});
|
||||
|
||||
const valid_recipient = keypair.getPublicKey();
|
||||
const valid_identity = keypair.getPrivateKey();
|
||||
const invalid_key = "not-a-valid-key";
|
||||
|
||||
try stdout.print("Is '{s}' a valid recipient? {}\n", .{ valid_recipient, age.isValidX25519Recipient(valid_recipient) });
|
||||
try stdout.print("Is '{s}' a valid identity? {}\n", .{ valid_identity, age.isValidX25519Identity(valid_identity) });
|
||||
try stdout.print("Is '{s}' a valid recipient? {}\n", .{ invalid_key, age.isValidX25519Recipient(invalid_key) });
|
||||
|
||||
const recipient_type = age.getRecipientType(valid_recipient);
|
||||
try stdout.print("Recipient type: {s}\n\n", .{@tagName(recipient_type)});
|
||||
|
||||
try stdout.flush();
|
||||
// Example 8: Deriving public key from private key
|
||||
try stdout.print("Example 8: Derive public key\n", .{});
|
||||
try stdout.print("-----------------------------\n", .{});
|
||||
|
||||
const derived_public = try age.derivePublicKey(gpa, keypair.getPrivateKey());
|
||||
defer gpa.free(derived_public);
|
||||
|
||||
try stdout.print("Original public: {s}\n", .{keypair.getPublicKey()});
|
||||
try stdout.print("Derived public: {s}\n", .{derived_public});
|
||||
try stdout.print("Keys match: {}\n\n", .{std.mem.eql(u8, keypair.getPublicKey(), derived_public)});
|
||||
|
||||
try stdout.flush();
|
||||
// Example 9: Error handling
|
||||
try stdout.print("Example 9: Error handling\n", .{});
|
||||
try stdout.print("-------------------------\n", .{});
|
||||
|
||||
// Try to decrypt with wrong key
|
||||
if (age.decrypt(encrypted.toSlice(), keypair2.getPrivateKey())) |_| {
|
||||
try stdout.print("Unexpected success!\n", .{});
|
||||
} else |err| {
|
||||
try stdout.print("Expected error: {s}\n", .{@errorName(err)});
|
||||
}
|
||||
|
||||
// Try to use invalid passphrase
|
||||
if (age.decryptPassphrase(pass_encrypted.toSlice(), "wrong-passphrase")) |_| {
|
||||
try stdout.print("Unexpected success!\n", .{});
|
||||
} else |err| {
|
||||
try stdout.print("Expected error: {s}\n", .{@errorName(err)});
|
||||
}
|
||||
|
||||
try stdout.print("\nAll examples completed successfully!\n", .{});
|
||||
|
||||
// Flush all output to ensure it's displayed
|
||||
try stdout.flush();
|
||||
}
|
||||
Reference in New Issue
Block a user