keypair

package
v1.25.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 19, 2026 License: MIT Imports: 13 Imported by: 0

README

keypair/ - Type-Safe Key Generation and Management

Foundation module providing type-safe cryptographic key pair generation and management through Go generics.

Test Coverage

Overview

The keypair module is the foundation of GoPKI, providing:

  • Type-safe key generation with compile-time guarantees
  • Unified KeyPair Manager interface across all algorithms
  • Multi-format support (PEM, DER, SSH, PKCS#12)
  • Secure file operations with enforced permissions
  • Algorithm flexibility (RSA, ECDSA, Ed25519)

🤖 AI Agent Quick Start

File Structure Map
keypair/
├── keypair.go           - START HERE: Core types, Manager, generic constraints
│                         Lines 50-150: Type constraints (CRITICAL)
│                         Manager implementation, format conversions, file operations
├── algo/                - Algorithm implementations
│   ├── rsa.go          - RSA key generation and operations
│   │                     Structure, validation, generation (2048/3072/4096)
│   │                     Format conversions (PEM/DER/SSH), file operations
│   ├── ecdsa.go        - ECDSA operations (P-224/256/384/521)
│   │                     ECDSA structures, curves, generation, validation
│   │                     Format support, SSH format specifics
│   ├── ed25519.go      - Ed25519 high-performance signing
│   │                     Ed25519 structures, generation functions
│   │                     Format conversions, SSH format
│   ├── rsa_test.go     - Comprehensive RSA tests
│   ├── ecdsa_test.go   - ECDSA algorithm tests
│   └── ed25519_test.go - Ed25519 tests
└── format/             - Format definitions
    └── format.go       - Type-safe format abstractions (PEM, DER, SSH)
Key Functions Location
Function File Purpose
Generate[T, K, P, B]() keypair.go Primary API - Generic key generation factory
Type Constraints keypair.go:50-150 CRITICAL - Read first: Param, KeyPair, PrivateKey, PublicKey
Manager struct keypair.go Unified interface for all key operations
ToPEM() keypair.go Convert Manager keys to PEM format
ToSSH() keypair.go Convert Manager keys to SSH format
SaveToPEM() keypair.go Save keys to PEM files (secure permissions)
LoadFromPEM[K, P, B]() keypair.go Load existing keys into Manager
GenerateRSAKeyPair() algo/rsa.go Direct RSA generation (alternative to Manager)
GenerateECDSAKeyPair() algo/ecdsa.go Direct ECDSA generation
GenerateEd25519KeyPair() algo/ed25519.go Direct Ed25519 generation
Common Modification Points

Adding New Algorithm:

  1. Create algo/newalgo.go following pattern from algo/rsa.go
  2. Define NewAlgoKeyPair struct with PrivateKey and PublicKey fields
  3. Implement GenerateNewAlgoKeyPair() function (see RSA generation pattern)
  4. Add format conversion methods following RSA patterns
  5. Update type constraints in keypair.go:50-150
  6. Add to test suite following algo/rsa_test.go patterns

Adding New Format:

  1. Define format type in format/format.go
  2. Add conversion functions in each algo/*.go file
  3. Add Manager support in keypair.go
  4. Add test coverage in *_test.go files

Fixing Key Generation Bug:

  1. Check test expectations in relevant algo/*_test.go
  2. Review generation logic in algo/*.go (generation functions)
  3. Verify parameter validation (check minimum key sizes, curves)
  4. Run: task test:specific -- TestGenerateRSAKeyPair (or relevant test)
  5. Check format conversions aren't affected
Type Relationships
// Core type constraints (keypair.go:50-150)
// ALL modules in GoPKI use these constraints

// Parameter types for key generation
type Param interface {
    algo.KeySize | algo.ECDSACurve | algo.Ed25519Config
}

// KeyPair types (algorithm-specific structures)
type KeyPair interface {
    *algo.RSAKeyPair | *algo.ECDSAKeyPair | *algo.Ed25519KeyPair
}

// Private key types (crypto/... standard library types)
type PrivateKey interface {
    *rsa.PrivateKey | *ecdsa.PrivateKey | ed25519.PrivateKey
}

// Public key types
type PublicKey interface {
    *rsa.PublicKey | *ecdsa.PublicKey | ed25519.PublicKey
}

// Usage pattern in this module:
func Generate[T Param, K KeyPair, P PrivateKey, B PublicKey](param T) (*Manager[K, P, B], error) {
    // Implementation provides compile-time type safety
}

// Usage pattern in OTHER modules (cert, signing, encryption):
func ProcessKey[T keypair.PrivateKey](key T) error {
    // Function works with all constraint types
}

Critical Understanding:

  • These constraints are used by ALL modules in GoPKI
  • Changing these affects cert/, signing/, encryption/, pkcs12/ modules
  • Always verify cross-module compatibility when modifying
Dependencies

This module depends on:

  • crypto/rsa - Standard library RSA support
  • crypto/ecdsa - Standard library ECDSA support
  • crypto/ed25519 - Standard library Ed25519 support
  • golang.org/x/crypto/ssh - SSH format support
  • encoding/pem - PEM encoding/decoding
  • encoding/asn1 - DER format support

Modules that depend on THIS:

  • cert/ - Uses KeyPair types for certificate creation
  • signing/ - Uses PrivateKey constraints for document signing
  • encryption/ - Uses PublicKey/PrivateKey for encryption operations
  • pkcs12/ - Uses key types for P12 bundling

Impact Warning: Changes to type constraints in keypair.go:50-150 affect ALL downstream modules!

Testing Strategy

Test Files:

  • keypair_test.go - Core Manager functionality tests
  • algo/rsa_test.go - RSA algorithm-specific tests (1,234 lines)
  • algo/ecdsa_test.go - ECDSA algorithm tests (1,156 lines)
  • algo/ed25519_test.go - Ed25519 algorithm tests (892 lines)
  • compatibility/keypair/ssh_test.go - SSH format compatibility with OpenSSH
  • compatibility/keypair/ssh_advanced_test.go - Advanced SSH features

Running Tests:

# This module only
go test ./keypair/...

# Manager tests specifically
task test:specific -- TestManager

# Algorithm-specific
task test:specific -- TestGenerateRSAKeyPair
task test:specific -- TestECDSAKeyPair
task test:specific -- TestEd25519KeyPair

# SSH compatibility
task test:compatibility

Test Coverage: 75.3% (3,282 lines of tests)


Features

Supported Algorithms
Algorithm Key Sizes Generation Format Support SSH Support
RSA 2048/3072/4096 bits PEM, DER, SSH, P12
ECDSA P-224/256/384/521 curves PEM, DER, SSH, P12
Ed25519 256-bit PEM, DER, SSH, P12
KeyPair Manager

The Manager provides a unified interface across all algorithms:

type Manager[K KeyPair, P PrivateKey, B PublicKey] struct {
    // Unified interface for RSA, ECDSA, Ed25519
}

Benefits:

  • Type Safety: Compile-time guarantees, no runtime type assertions
  • Unified API: Same interface for all algorithms
  • Format Agnostic: Easy conversion between PEM/DER/SSH/P12
  • Secure Operations: Built-in secure file permissions

Installation

go get github.com/jasoet/gopki/keypair

Quick Start

package main

import (
    "crypto/rsa"
    "fmt"
    "github.com/jasoet/gopki/keypair"
    "github.com/jasoet/gopki/keypair/algo"
)

func main() {
    // Generate RSA key pair with Manager
    manager, err := keypair.Generate[algo.KeySize, *algo.RSAKeyPair, *rsa.PrivateKey, *rsa.PublicKey](algo.KeySize2048)
    if err != nil {
        panic(err)
    }

    // Extract keys with type safety
    privateKey := manager.PrivateKey()
    publicKey := manager.PublicKey()

    // Convert to different formats
    privatePEM, publicPEM, _ := manager.ToPEM()
    privateDER, publicDER, _ := manager.ToDER()
    privateSSH, publicSSH, _ := manager.ToSSH("user@host", "")

    // Save with secure permissions (0600 for private, 0644 for public)
    manager.SaveToPEM("private.pem", "public.pem")
    manager.SaveToSSH("id_rsa", "id_rsa.pub", "user@host", "")

    fmt.Printf("Generated %d-bit RSA key pair\n", privateKey.Size()*8)
}
Method 2: Direct Algorithm Usage
package main

import (
    "fmt"
    "github.com/jasoet/gopki/keypair/algo"
)

func main() {
    // Generate RSA key pair directly
    rsaKeys, _ := algo.GenerateRSAKeyPair(algo.KeySize2048)

    // Generate ECDSA key pair
    ecdsaKeys, _ := algo.GenerateECDSAKeyPair(algo.P256)

    // Generate Ed25519 key pair
    ed25519Keys, _ := algo.GenerateEd25519KeyPair()

    fmt.Println("Keys generated successfully")
}

API Reference

Key Generation
// Generic generation with Manager
func Generate[T Param, K KeyPair, P PrivateKey, B PublicKey](param T) (*Manager[K, P, B], error)

// Examples:
import (
    "crypto/rsa"
    "crypto/ecdsa"
    "crypto/ed25519"
)

// RSA Manager
manager, _ := keypair.Generate[algo.KeySize, *algo.RSAKeyPair, *rsa.PrivateKey, *rsa.PublicKey](algo.KeySize2048)

// ECDSA Manager
manager, _ := keypair.Generate[algo.ECDSACurve, *algo.ECDSAKeyPair, *ecdsa.PrivateKey, *ecdsa.PublicKey](algo.P256)

// Ed25519 Manager
manager, _ := keypair.Generate[algo.Ed25519Config, *algo.Ed25519KeyPair, ed25519.PrivateKey, ed25519.PublicKey](algo.Ed25519Default)
Direct Algorithm Functions
// RSA (2048/3072/4096 bits)
func algo.GenerateRSAKeyPair(keySize algo.KeySize) (*algo.RSAKeyPair, error)

// ECDSA (P-224/P-256/P-384/P-521)
func algo.GenerateECDSAKeyPair(curve algo.ECDSACurve) (*algo.ECDSAKeyPair, error)

// Ed25519 (256-bit)
func algo.GenerateEd25519KeyPair() (*algo.Ed25519KeyPair, error)
Manager Operations
// Key extraction
func (m *Manager[K, P, B]) PrivateKey() P
func (m *Manager[K, P, B]) PublicKey() B
func (m *Manager[K, P, B]) KeyPair() K

// Format conversion
func (m *Manager[K, P, B]) ToPEM() (privateFormat.PEM, publicFormat.PEM, error)
func (m *Manager[K, P, B]) ToDER() (privateFormat.DER, publicFormat.DER, error)
func (m *Manager[K, P, B]) ToSSH(comment, passphrase string) (privateFormat.SSH, publicFormat.SSH, error)

// File operations (secure permissions: 0600 for private, 0644 for public)
func (m *Manager[K, P, B]) SaveToPEM(privateFile, publicFile string) error
func (m *Manager[K, P, B]) SaveToDER(privateFile, publicFile string) error
func (m *Manager[K, P, B]) SaveToSSH(privateFile, publicFile, comment, passphrase string) error

// Validation
func (m *Manager[K, P, B]) Validate() error
func (m *Manager[K, P, B]) IsValid() bool

// Metadata
func (m *Manager[K, P, B]) GetInfo() (*KeyInfo, error)
Loading Existing Keys
// Load into Manager from different formats
func LoadFromPEM[K KeyPair, P PrivateKey, B PublicKey](privateKeyFile string) (*Manager[K, P, B], error)
func LoadFromDER[K KeyPair, P PrivateKey, B PublicKey](privateKeyFile string) (*Manager[K, P, B], error)
func LoadFromSSH[K KeyPair, P PrivateKey, B PublicKey](privateKeyFile, passphrase string) (*Manager[K, P, B], error)

// Example:
manager, _ := keypair.LoadFromPEM[*algo.RSAKeyPair, *rsa.PrivateKey, *rsa.PublicKey]("private.pem")
Format Conversion (Direct Functions)
// PEM format
func PrivateKeyToPEM[T PrivateKey](privateKey T) (format.PEM, error)
func PublicKeyToPEM[T PublicKey](publicKey T) (format.PEM, error)
func ParsePrivateKeyFromPEM[T PrivateKey](pemData format.PEM) (T, error)

// DER format
func PrivateKeyToDER[T PrivateKey](privateKey T) (format.DER, error)
func PublicKeyToDER[T PublicKey](publicKey T) (format.DER, error)

// SSH format
func PrivateKeyToSSH[T PrivateKey](privateKey T, comment, passphrase string) (format.SSH, error)
func PublicKeyToSSH[T PublicKey](publicKey T, comment string) (format.SSH, error)

Usage Examples

Complete Key Management Workflow
package main

import (
    "crypto/rsa"
    "fmt"
    "github.com/jasoet/gopki/keypair"
    "github.com/jasoet/gopki/keypair/algo"
)

func main() {
    // 1. Generate key pair
    manager, err := keypair.Generate[algo.KeySize, *algo.RSAKeyPair, *rsa.PrivateKey, *rsa.PublicKey](algo.KeySize2048)
    if err != nil {
        panic(err)
    }

    // 2. Validate key pair
    if !manager.IsValid() {
        panic("Invalid key pair")
    }

    // 3. Get key information
    info, _ := manager.GetInfo()
    fmt.Printf("Algorithm: %s, Key Size: %d bits\n", info.Algorithm, info.KeySize)

    // 4. Save in multiple formats
    manager.SaveToPEM("keys/private.pem", "keys/public.pem")
    manager.SaveToDER("keys/private.der", "keys/public.der")
    manager.SaveToSSH("keys/id_rsa", "keys/id_rsa.pub", "user@host", "")

    // 5. Load existing key
    loaded, _ := keypair.LoadFromPEM[*algo.RSAKeyPair, *rsa.PrivateKey, *rsa.PublicKey]("keys/private.pem")

    // 6. Extract keys for use with other modules
    privateKey := loaded.PrivateKey()
    publicKey := loaded.PublicKey()

    fmt.Printf("Private key size: %d bits\n", privateKey.Size()*8)
    fmt.Printf("Public key: %v\n", publicKey)
}
Multi-Algorithm Key Generation
package main

import (
    "crypto/ecdsa"
    "crypto/ed25519"
    "crypto/rsa"
    "fmt"
    "github.com/jasoet/gopki/keypair"
    "github.com/jasoet/gopki/keypair/algo"
)

func main() {
    // Generate RSA 2048-bit
    rsa2048, _ := keypair.Generate[algo.KeySize, *algo.RSAKeyPair, *rsa.PrivateKey, *rsa.PublicKey](algo.KeySize2048)

    // Generate ECDSA P-256
    ecdsaP256, _ := keypair.Generate[algo.ECDSACurve, *algo.ECDSAKeyPair, *ecdsa.PrivateKey, *ecdsa.PublicKey](algo.P256)

    // Generate Ed25519
    ed25519Key, _ := keypair.Generate[algo.Ed25519Config, *algo.Ed25519KeyPair, ed25519.PrivateKey, ed25519.PublicKey](algo.Ed25519Default)

    // All use same Manager API
    rsa2048.SaveToPEM("rsa_private.pem", "rsa_public.pem")
    ecdsaP256.SaveToPEM("ecdsa_private.pem", "ecdsa_public.pem")
    ed25519Key.SaveToPEM("ed25519_private.pem", "ed25519_public.pem")

    fmt.Println("All keys generated and saved")
}
SSH Key Format
package main

import (
    "crypto/ed25519"
    "github.com/jasoet/gopki/keypair"
    "github.com/jasoet/gopki/keypair/algo"
)

func main() {
    // Generate Ed25519 key pair
    manager, _ := keypair.Generate[algo.Ed25519Config, *algo.Ed25519KeyPair, ed25519.PrivateKey, ed25519.PublicKey](algo.Ed25519Default)

    // Save as SSH keys with passphrase protection
    comment := "user@hostname"
    passphrase := "secure_passphrase_2024"

    manager.SaveToSSH("~/.ssh/id_ed25519", "~/.ssh/id_ed25519.pub", comment, passphrase)

    // Load SSH key
    loaded, _ := keypair.LoadFromSSH[*algo.Ed25519KeyPair, ed25519.PrivateKey, ed25519.PublicKey]("~/.ssh/id_ed25519", passphrase)

    // Convert to OpenSSH authorized_keys format
    _, publicSSH, _ := loaded.ToSSH(comment, "")
    fmt.Println("Public key for authorized_keys:")
    fmt.Println(string(publicSSH))
}

Security Features

Enforced Security Standards
// Minimum key sizes enforced at compile time
algo.GenerateRSAKeyPair(algo.KeySize1024) // ❌ Compile error - minimum 2048 bits
algo.GenerateRSAKeyPair(algo.KeySize2048) // ✅ Accepted

// Secure curves only
algo.GenerateECDSAKeyPair(algo.P256) // ✅ NIST P-256 curve
// Weak curves not available in API

// Strong random source
// Uses crypto/rand.Reader exclusively - no configurable random source
Secure File Operations
// Private keys saved with 0600 permissions (owner read/write only)
manager.SaveToPEM("private.pem", "public.pem")
// private.pem: -rw------- (0600)
// public.pem:  -rw-r--r-- (0644)

// Directories created with 0700 permissions (owner access only)
manager.SaveToPEM("keys/private.pem", "keys/public.pem")
// keys/: drwx------ (0700)
Memory Safety
  • No raw key material exposure in public APIs
  • Type-safe interfaces prevent runtime type errors
  • Defensive copying of sensitive parameters
  • Zero runtime overhead from generic constraints

Testing

Run Tests
# All keypair module tests
go test ./keypair/...

# Manager tests only
task test:specific -- TestManager

# Algorithm-specific tests
task test:specific -- TestGenerateRSAKeyPair
task test:specific -- TestECDSAKeyPair
task test:specific -- TestEd25519KeyPair

# Format conversion tests
task test:specific -- TestToPEM
task test:specific -- TestToSSH

# SSH compatibility tests with ssh-keygen
task test:compatibility
Test Coverage

Module Coverage: 75.3%

  • keypair.go - Manager and core functionality
  • algo/rsa.go - RSA implementation
  • algo/ecdsa.go - ECDSA implementation
  • algo/ed25519.go - Ed25519 implementation
  • Format conversion functions
  • File operations and validation

Test Files:

  • keypair_test.go - Core Manager tests
  • algo/rsa_test.go - Comprehensive RSA tests
  • algo/ecdsa_test.go - ECDSA algorithm tests
  • algo/ed25519_test.go - Ed25519 algorithm tests
  • compatibility/keypair/ssh_test.go - OpenSSH compatibility
  • compatibility/keypair/ssh_advanced_test.go - Advanced SSH features

Integration with Other Modules

With cert/ Module
// Generate key pair
manager, _ := keypair.Generate[algo.KeySize, *algo.RSAKeyPair, *rsa.PrivateKey, *rsa.PublicKey](algo.KeySize2048)

// Extract key pair for certificate creation
keyPair := manager.KeyPair()

// Create certificate (uses keypair types)
certificate, _ := cert.CreateSelfSignedCertificate(keyPair, cert.CertificateRequest{...})
With signing/ Module
// Use private key for document signing
privateKey := manager.PrivateKey()

// Sign document (uses keypair.PrivateKey constraint)
signature, _ := signing.SignData(document, privateKey, certificate, opts)
With encryption/ Module
// Use public key for encryption
publicKey := manager.PublicKey()

// Encrypt data (uses keypair.PublicKey constraint)
encrypted, _ := encryption.EncryptWithPublicKey(data, publicKey, opts)
With pkcs12/ Module
// Create PKCS#12 bundle with key pair
privateKey := manager.PrivateKey()

// Bundle with certificate
pkcs12.CreateP12File("bundle.p12", privateKey, certificate, caChain, opts)

Best Practices

  1. Use Manager API: Prefer keypair.Generate() with Manager over direct algorithm functions for consistency

  2. Type Constraints: Always use the provided type constraints (keypair.PrivateKey, keypair.PublicKey, keypair.KeyPair)

  3. Secure Storage: Use Manager's SaveTo*() methods for automatic secure permissions

  4. Key Sizes: Use RSA ≥3072 bits for long-term security, 2048 for general use

  5. Algorithm Selection:

    • RSA: Maximum compatibility, certificate-based workflows
    • ECDSA: Modern choice, smaller keys, full feature support
    • Ed25519: High performance signing, fast key generation
  6. Format Choice:

    • PEM: Human-readable, most common, good for certificates
    • DER: Binary, ~30% smaller, good for performance
    • SSH: OpenSSH compatibility, authorized_keys format
    • PKCS#12: Password-protected bundles with certificates
  7. Validation: Always validate keys after loading with manager.Validate()

  8. Passphrase Protection: Use strong passphrases for SSH private keys in production

Troubleshooting

Common Issues

Issue: Compile error with generic types

// ❌ Wrong: Missing type parameters
manager, _ := keypair.Generate(algo.KeySize2048)

// ✅ Correct: All type parameters specified
manager, _ := keypair.Generate[algo.KeySize, *algo.RSAKeyPair, *rsa.PrivateKey, *rsa.PublicKey](algo.KeySize2048)

Issue: File permission denied

// Check file permissions
// Private keys should be 0600 (owner read/write only)
// Public keys should be 0644 (owner read/write, others read)

Issue: SSH key not accepted by ssh-keygen

// Ensure correct SSH format
privateSSH, publicSSH, _ := manager.ToSSH("user@host", "")
// Public key should start with algorithm name (ssh-rsa, ecdsa-sha2-nistp256, ssh-ed25519)

Performance Considerations

Key Generation Performance
Algorithm Key Size Time (approx)
RSA 2048-bit ~50-100ms
RSA 3072-bit ~200-400ms
RSA 4096-bit ~1-2s
ECDSA P-256 ~5-10ms
ECDSA P-384 ~10-20ms
Ed25519 256-bit ~1-2ms

Recommendation: Ed25519 for best performance, ECDSA P-256 for balance, RSA 2048 for compatibility

Memory Usage
  • RSA keys: ~2KB (2048-bit), ~4KB (4096-bit)
  • ECDSA keys: ~100 bytes (P-256), ~200 bytes (P-384)
  • Ed25519 keys: ~64 bytes

Recommendation: ECDSA or Ed25519 for memory-constrained environments

Further Reading

License

MIT License - see LICENSE file


Part of GoPKI - Type-Safe Cryptography for Production

Documentation

Overview

Package keypair provides type-safe cryptographic key pair generation and management using Go generics for compile-time type safety. It supports RSA, ECDSA, and Ed25519 algorithms with unified interfaces and format conversion utilities.

The package uses generic constraints to ensure type safety at compile time:

  • Param interface constrains key generation parameters
  • KeyPair interface constrains key pair types
  • PublicKey and PrivateKey interfaces constrain key types

Example usage:

// Generate RSA key pair
rsaKeys, err := GenerateKeyPair[algo.KeySize, *algo.RSAKeyPair](2048)

// Generate ECDSA key pair
ecdsaKeys, err := GenerateKeyPair[algo.ECDSACurve, *algo.ECDSAKeyPair](algo.P256)

// Generate Ed25519 key pair
ed25519Keys, err := GenerateKeyPair[algo.Ed25519Config, *algo.Ed25519KeyPair]("")

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func FromDERFiles

func FromDERFiles[K KeyPair](privateFile, publicFile string) (K, error)

FromDERFiles loads a key pair from separate private and public key files in DER format. The function reads both files and reconstructs the appropriate KeyPair type.

Type parameter:

  • K: KeyPair type (*algo.RSAKeyPair, *algo.ECDSAKeyPair, or *algo.Ed25519KeyPair)

Parameters:

  • privateFile: Path to the private key DER file
  • publicFile: Path to the public key DER file

Returns the reconstructed key pair or an error if reading or parsing fails.

Example:

ecdsaKeyPair, err := FromDERFiles[*algo.ECDSAKeyPair]("private.der", "public.der")
if err != nil {
	log.Printf("Failed to load key pair: %v", err)
}

func FromPEMFiles

func FromPEMFiles[K KeyPair](privateFile, publicFile string) (K, error)

FromPEMFiles loads a key pair from separate private and public key files in PEM format. The function reads both files and reconstructs the appropriate KeyPair type.

Type parameter:

  • K: KeyPair type (*algo.RSAKeyPair, *algo.ECDSAKeyPair, or *algo.Ed25519KeyPair)

Parameters:

  • privateFile: Path to the private key PEM file
  • publicFile: Path to the public key PEM file

Returns the reconstructed key pair or an error if reading or parsing fails.

Example:

rsaKeyPair, err := FromPEMFiles[*algo.RSAKeyPair]("private.pem", "public.pem")
if err != nil {
	log.Printf("Failed to load key pair: %v", err)
}

func FromSSHFiles

func FromSSHFiles[K KeyPair](privateFile, publicFile string, passphrase string) (K, error)

FromSSHFiles loads a key pair from separate private and public key files in SSH format. The function reads both files and reconstructs the appropriate KeyPair type.

Type parameter:

  • K: KeyPair type (*algo.RSAKeyPair, *algo.ECDSAKeyPair, or *algo.Ed25519KeyPair)

Parameters:

  • privateFile: Path to the SSH private key file
  • publicFile: Path to the SSH public key file
  • passphrase: Passphrase for encrypted private keys (empty string for unencrypted)

Returns the reconstructed key pair or an error if reading or parsing fails.

Example:

ed25519KeyPair, err := FromSSHFiles[*algo.Ed25519KeyPair]("id_ed25519", "id_ed25519.pub", "passphrase")
if err != nil {
	log.Printf("Failed to load key pair: %v", err)
}

func GetPrivateKeyFromKeyPair

func GetPrivateKeyFromKeyPair[K KeyPair, T PrivateKey](keyPair K) (T, error)

GetPrivateKeyFromKeyPair extracts the private key from a KeyPair with type safety. This function works with all supported KeyPair types and maintains type relationships.

Type parameters:

  • K: KeyPair type (*algo.RSAKeyPair, *algo.ECDSAKeyPair, or *algo.Ed25519KeyPair)
  • T: Expected private key type (*rsa.PrivateKey, *ecdsa.PrivateKey, or ed25519.PrivateKey)

Parameters:

  • keyPair: The key pair from which to extract the private key

Returns the corresponding private key or an error if extraction fails or type mismatch occurs.

Examples:

// Extract RSA private key with explicit types
rsaPriv, err := GetPrivateKeyFromKeyPair[*algo.RSAKeyPair, *rsa.PrivateKey](rsaKeyPair)

// Extract ECDSA private key with type inference
ecdsaPriv, err := GetPrivateKeyFromKeyPair[*algo.ECDSAKeyPair, *ecdsa.PrivateKey](ecdsaKeyPair)

// Extract Ed25519 private key
ed25519Priv, err := GetPrivateKeyFromKeyPair[*algo.Ed25519KeyPair, ed25519.PrivateKey](ed25519KeyPair)

func GetPublicKey

func GetPublicKey[TPriv PrivateKey, TPub PublicKey](privateKey TPriv) (TPub, error)

GetPublicKey extracts the public key from a private key with type safety. This function works with all supported key types and maintains type relationships.

Type parameters:

  • TPriv: Private key type (*rsa.PrivateKey, *ecdsa.PrivateKey, or ed25519.PrivateKey)
  • TPub: Expected public key type (*rsa.PublicKey, *ecdsa.PublicKey, or ed25519.PublicKey)

Parameters:

  • privateKey: The private key from which to extract the public key

Returns the corresponding public key or an error if extraction fails.

Example:

rsaPublicKey, err := GetPublicKey[*rsa.PrivateKey, *rsa.PublicKey](rsaPrivateKey)
if err != nil {
	log.Printf("Failed to get public key: %v", err)
}

func GetPublicKeyFromKeyPair

func GetPublicKeyFromKeyPair[K KeyPair, T PublicKey](keyPair K) (T, error)

GetPublicKeyFromKeyPair extracts the public key from a KeyPair with type safety. This function works with all supported KeyPair types and maintains type relationships.

Type parameters:

  • K: KeyPair type (*algo.RSAKeyPair, *algo.ECDSAKeyPair, or *algo.Ed25519KeyPair)
  • T: Expected public key type (*rsa.PublicKey, *ecdsa.PublicKey, or ed25519.PublicKey)

Parameters:

  • keyPair: The key pair from which to extract the public key

Returns the corresponding public key or an error if extraction fails or type mismatch occurs.

Examples:

// Extract RSA public key with explicit types
rsaPub, err := GetPublicKeyFromKeyPair[*algo.RSAKeyPair, *rsa.PublicKey](rsaKeyPair)

// Extract ECDSA public key with type inference
ecdsaPub, err := GetPublicKeyFromKeyPair[*algo.ECDSAKeyPair, *ecdsa.PublicKey](ecdsaKeyPair)

// Extract Ed25519 public key
ed25519Pub, err := GetPublicKeyFromKeyPair[*algo.Ed25519KeyPair, ed25519.PublicKey](ed25519KeyPair)

func PrivateKeyFromSSH

func PrivateKeyFromSSH[T PrivateKey](sshData format.SSH, passphrase string) (T, error)

PrivateKeyFromSSH parses a private key from SSH-encoded data. The function handles OpenSSH format with optional passphrase decryption.

Type parameter:

  • T: Expected private key type (*rsa.PrivateKey, *ecdsa.PrivateKey, or ed25519.PrivateKey)

Parameters:

  • sshData: SSH-encoded private key data
  • passphrase: Passphrase for encrypted keys (empty string for unencrypted)

Returns the parsed private key or an error if parsing fails or type assertion fails.

Example:

ed25519PrivKey, err := PrivateKeyFromSSH[ed25519.PrivateKey](sshData, "passphrase")
if err != nil {
	log.Printf("Failed to parse private key: %v", err)
}

func PrivateKeyToDER

func PrivateKeyToDER[T PrivateKey](privateKey T) (format.DER, error)

PrivateKeyToDER converts a private key to DER-encoded format. The key is marshaled using PKCS#8 format for maximum compatibility.

Type parameter:

  • T: Private key type (*rsa.PrivateKey, *ecdsa.PrivateKey, or ed25519.PrivateKey)

Parameters:

  • privateKey: The private key to convert

Returns DER-encoded data or an error if conversion fails.

Example:

derData, err := PrivateKeyToDER(rsaPrivateKey)
if err != nil {
	log.Printf("Failed to convert private key: %v", err)
}

func PrivateKeyToPEM

func PrivateKeyToPEM[T PrivateKey](privateKey T) (format.PEM, error)

PrivateKeyToPEM converts a private key to PEM-encoded format. The key is marshaled using PKCS#8 format for maximum compatibility.

Type parameter:

  • T: Private key type (*rsa.PrivateKey, *ecdsa.PrivateKey, or ed25519.PrivateKey)

Parameters:

  • privateKey: The private key to convert

Returns PEM-encoded data or an error if conversion fails.

Example:

pemData, err := PrivateKeyToPEM(rsaPrivateKey)
if err != nil {
	log.Printf("Failed to convert private key: %v", err)
}

func PrivateKeyToSSH

func PrivateKeyToSSH[T PrivateKey](privateKey T, comment string, passphrase string) (format.SSH, error)

PrivateKeyToSSH converts a private key to SSH-encoded format. The key is marshaled using OpenSSH private key format with optional passphrase protection.

Type parameter:

  • T: Private key type (*rsa.PrivateKey, *ecdsa.PrivateKey, or ed25519.PrivateKey)

Parameters:

  • privateKey: The private key to convert
  • comment: Optional comment to embed in the key file
  • passphrase: Optional passphrase for key encryption (empty string for unencrypted)

Returns SSH-encoded data or an error if conversion fails.

Security note: Using a passphrase is recommended for private key storage.

Example:

sshData, err := PrivateKeyToSSH(rsaPrivateKey, "my-key", "secure-passphrase")
if err != nil {
	log.Printf("Failed to convert private key: %v", err)
}

func PublicKeyFromDER

func PublicKeyFromDER[T PublicKey](derData format.DER) (T, error)

PublicKeyFromDER parses a public key from DER-encoded data. The function expects PKIX format and returns the appropriate public key type.

Type parameter:

  • T: Expected public key type (*rsa.PublicKey, *ecdsa.PublicKey, or ed25519.PublicKey)

Parameters:

  • derData: DER-encoded public key data

Returns the parsed public key or an error if parsing fails or type assertion fails.

Example:

ecdsaPubKey, err := PublicKeyFromDER[*ecdsa.PublicKey](derData)
if err != nil {
	log.Printf("Failed to parse public key: %v", err)
}

func PublicKeyFromPEM

func PublicKeyFromPEM[T PublicKey](pemData format.PEM) (T, error)

PublicKeyFromPEM parses a public key from PEM-encoded data. The function expects PKIX format and returns the appropriate public key type.

Type parameter:

  • T: Expected public key type (*rsa.PublicKey, *ecdsa.PublicKey, or ed25519.PublicKey)

Parameters:

  • pemData: PEM-encoded public key data

Returns the parsed public key or an error if parsing fails or type assertion fails.

Example:

rsaPubKey, err := PublicKeyFromPEM[*rsa.PublicKey](pemData)
if err != nil {
	log.Printf("Failed to parse public key: %v", err)
}

func PublicKeyFromSSH

func PublicKeyFromSSH[T PublicKey](sshData format.SSH) (T, error)

PublicKeyFromSSH parses a public key from SSH-encoded data. The function handles SSH public key format (authorized_keys format).

Type parameter:

  • T: Expected public key type (*rsa.PublicKey, *ecdsa.PublicKey, or ed25519.PublicKey)

Parameters:

  • sshData: SSH-encoded public key data

Returns the parsed public key or an error if parsing fails or type assertion fails.

Example:

ed25519PubKey, err := PublicKeyFromSSH[ed25519.PublicKey](sshData)
if err != nil {
	log.Printf("Failed to parse public key: %v", err)
}

func PublicKeyToDER

func PublicKeyToDER[T PublicKey](publicKey T) (format.DER, error)

PublicKeyToDER converts a public key to DER-encoded format. The key is marshaled using PKIX format for standard compatibility.

Type parameter:

  • T: Public key type (*rsa.PublicKey, *ecdsa.PublicKey, or ed25519.PublicKey)

Parameters:

  • publicKey: The public key to convert

Returns DER-encoded data or an error if conversion fails.

Example:

derData, err := PublicKeyToDER(rsaPublicKey)
if err != nil {
	log.Printf("Failed to convert public key: %v", err)
}

func PublicKeyToPEM

func PublicKeyToPEM[T PublicKey](publicKey T) (format.PEM, error)

PublicKeyToPEM converts a public key to PEM-encoded format. The key is marshaled using PKIX format for standard compatibility.

Type parameter:

  • T: Public key type (*rsa.PublicKey, *ecdsa.PublicKey, or ed25519.PublicKey)

Parameters:

  • publicKey: The public key to convert

Returns PEM-encoded data or an error if conversion fails.

Example:

pemData, err := PublicKeyToPEM(rsaPublicKey)
if err != nil {
	log.Printf("Failed to convert public key: %v", err)
}

func PublicKeyToSSH

func PublicKeyToSSH[T PublicKey](publicKey T, comment string) (format.SSH, error)

PublicKeyToSSH converts a public key to SSH-encoded format. The key is marshaled using SSH public key format suitable for authorized_keys files.

Type parameter:

  • T: Public key type (*rsa.PublicKey, *ecdsa.PublicKey, or ed25519.PublicKey)

Parameters:

  • publicKey: The public key to convert
  • comment: Optional comment to include in the SSH key (commonly username@hostname)

Returns SSH-encoded data in format "ssh-rsa base64-key [comment]" or an error if conversion fails.

Example:

sshData, err := PublicKeyToSSH(rsaPublicKey, "user@example.com")
if err != nil {
	log.Printf("Failed to convert public key: %v", err)
}

func ToDERFiles

func ToDERFiles[T KeyPair](keyPair T, privateFile, publicFile string) error

ToDERFiles saves a key pair to separate private and public key files in DER format. The function creates the necessary directory structure and sets appropriate file permissions.

Type parameter:

  • T: Key pair type (*algo.RSAKeyPair, *algo.ECDSAKeyPair, or *algo.Ed25519KeyPair)

Parameters:

  • keyPair: The key pair to save
  • privateFile: Path where the private key will be saved
  • publicFile: Path where the public key will be saved

File permissions:

  • Private key files: 0600 (readable/writable by owner only)
  • Public key files: 0600 (for consistency, though public keys could be more permissive)
  • Directories: 0700 (accessible by owner only)

Example:

err := ToDERFiles(rsaKeyPair, "private.der", "public.der")
if err != nil {
	log.Printf("Failed to save key pair: %v", err)
}

func ToPEMFiles

func ToPEMFiles[T KeyPair](keyPair T, privateFile, publicFile string) error

ToPEMFiles saves a key pair to separate private and public key files in PEM format. The function creates the necessary directory structure and sets appropriate file permissions.

Type parameter:

  • T: Key pair type (*algo.RSAKeyPair, *algo.ECDSAKeyPair, or *algo.Ed25519KeyPair)

Parameters:

  • keyPair: The key pair to save
  • privateFile: Path where the private key will be saved
  • publicFile: Path where the public key will be saved

File permissions:

  • Private key files: 0600 (readable/writable by owner only)
  • Public key files: 0600 (for consistency, though public keys could be more permissive)
  • Directories: 0700 (accessible by owner only)

Example:

err := ToPEMFiles(rsaKeyPair, "private.pem", "public.pem")
if err != nil {
	log.Printf("Failed to save key pair: %v", err)
}

func ToSSHFiles

func ToSSHFiles[T KeyPair](keyPair T, privateFile, publicFile string, comment string, passphrase string) error

ToSSHFiles saves a key pair to separate private and public key files in SSH format. The function creates the necessary directory structure and sets appropriate file permissions.

Type parameter:

  • T: Key pair type (*algo.RSAKeyPair, *algo.ECDSAKeyPair, or *algo.Ed25519KeyPair)

Parameters:

  • keyPair: The key pair to save
  • privateFile: Path where the private key will be saved
  • publicFile: Path where the public key will be saved
  • comment: Optional comment to include in the SSH keys
  • passphrase: Optional passphrase for private key encryption (empty string for unencrypted)

File permissions:

  • Private key files: 0600 (readable/writable by owner only)
  • Public key files: 0600 (for consistency, though public keys could be more permissive)
  • Directories: 0700 (accessible by owner only)

Example:

err := ToSSHFiles(rsaKeyPair, "id_rsa", "id_rsa.pub", "user@host", "passphrase")
if err != nil {
	log.Printf("Failed to save key pair: %v", err)
}

Types

type GenericKeyPair

type GenericKeyPair any

GenericKeyPair represents any keypair type for functions that need to work with multiple keypair types dynamically

type GenericPrivateKey

type GenericPrivateKey any

GenericPrivateKey represents any private key type for functions that need to work with multiple key types dynamically

type GenericPublicKey

type GenericPublicKey any

GenericPublicKey represents any public key type for functions that need to work with multiple key types dynamically

type KeyInfo

type KeyInfo struct {
	Algorithm string // "RSA", "ECDSA", "Ed25519"
	KeySize   int    // Bits for RSA, curve size for ECDSA, 256 for Ed25519
	Curve     string // For ECDSA: "P-256", "P-384", "P-521", etc. Empty for RSA and Ed25519
}

KeyInfo contains metadata about a cryptographic key pair. This information is useful for identifying key properties and ensuring compatibility with different cryptographic operations.

type KeyPair

type KeyPair interface {
	*algo.RSAKeyPair | *algo.ECDSAKeyPair | *algo.Ed25519KeyPair
}

KeyPair defines the constraint for key pair types. It accepts pointers to RSAKeyPair, ECDSAKeyPair, or Ed25519KeyPair.

type Manager

type Manager[K KeyPair, P PrivateKey, B PublicKey] struct {
	// contains filtered or unexported fields
}

Manager provides type-safe operations for cryptographic key pairs. It encapsulates a key pair and provides methods for format conversion, validation, comparison, and file I/O operations while maintaining type safety through generics.

Type parameter:

  • K: KeyPair type (*algo.RSAKeyPair, *algo.ECDSAKeyPair, or *algo.Ed25519KeyPair)

Example usage:

// Generate an RSA key pair manager
manager, err := Generate[algo.KeySize, *algo.RSAKeyPair](algo.KeySize2048)

// Extract keys
privateKey := manager.PrivateKey()
publicKey := manager.PublicKey()

// Convert to formats
privatePEM, publicPEM, err := manager.ToPEM()

// Save to files
err = manager.SaveToPEM("private.pem", "public.pem")

func Generate

func Generate[T Param, K KeyPair, P PrivateKey, B PublicKey](param T) (*Manager[K, P, B], error)

Generate creates a new KeyPairManager with a freshly generated key pair. This factory method generates a key pair using the specified parameters and wraps it in a manager.

Type parameters:

  • T: Parameter type (algo.KeySize, algo.ECDSACurve, or algo.Ed25519Config)
  • K: KeyPair type (*algo.RSAKeyPair, *algo.ECDSAKeyPair, or *algo.Ed25519KeyPair)

Parameters:

  • param: Algorithm-specific parameter (key size, curve, or config)

Returns a new KeyPairManager instance or an error if generation fails.

Examples:

// Generate RSA key pair manager
rsaManager, err := Generate[algo.KeySize, *algo.RSAKeyPair](algo.KeySize2048)

// Generate ECDSA key pair manager
ecdsaManager, err := Generate[algo.ECDSACurve, *algo.ECDSAKeyPair](algo.P256)

// Generate Ed25519 key pair manager
ed25519Manager, err := Generate[algo.Ed25519Config, *algo.Ed25519KeyPair]("")

func LoadFromDER

func LoadFromDER[K KeyPair, P PrivateKey, B PublicKey](privateKeyFile string) (*Manager[K, P, B], error)

LoadFromDER creates a new KeyPairManager by loading a private key from a DER file. The public key is automatically derived from the private key.

Type parameter:

  • K: KeyPair type (*algo.RSAKeyPair, *algo.ECDSAKeyPair, or *algo.Ed25519KeyPair)

Parameters:

  • privateKeyFile: Path to the DER-encoded private key file

Returns a new KeyPairManager instance or an error if loading fails.

Example:

manager, err := LoadFromDER[*algo.ECDSAKeyPair]("private.der")
if err != nil {
	log.Printf("Failed to load key pair: %v", err)
}

func LoadFromDERData

func LoadFromDERData[K KeyPair, P PrivateKey, B PublicKey](privateKeyDER format.DER) (*Manager[K, P, B], error)

LoadFromDERData creates a new KeyPairManager by parsing private key data in DER format. The public key is automatically derived from the private key.

Type parameter:

  • K: KeyPair type (*algo.RSAKeyPair, *algo.ECDSAKeyPair, or *algo.Ed25519KeyPair)

Parameters:

  • privateKeyDER: DER-encoded private key data

Returns a new KeyPairManager instance or an error if parsing fails.

Example:

manager, err := LoadFromDERData[*algo.ECDSAKeyPair](derData)
if err != nil {
	log.Printf("Failed to load key pair: %v", err)
}

func LoadFromPEM

func LoadFromPEM[K KeyPair, P PrivateKey, B PublicKey](privateKeyFile string) (*Manager[K, P, B], error)

LoadFromPEM creates a new KeyPairManager by loading a private key from a PEM file. The public key is automatically derived from the private key.

Type parameter:

  • K: KeyPair type (*algo.RSAKeyPair, *algo.ECDSAKeyPair, or *algo.Ed25519KeyPair)

Parameters:

  • privateKeyFile: Path to the PEM-encoded private key file

Returns a new KeyPairManager instance or an error if loading fails.

Example:

manager, err := LoadFromPEM[*algo.RSAKeyPair]("private.pem")
if err != nil {
	log.Printf("Failed to load key pair: %v", err)
}

func LoadFromPEMData

func LoadFromPEMData[K KeyPair, P PrivateKey, B PublicKey](privateKeyPEM format.PEM) (*Manager[K, P, B], error)

LoadFromPEMData creates a new KeyPairManager by parsing private key data in PEM format. The public key is automatically derived from the private key.

Type parameter:

  • K: KeyPair type (*algo.RSAKeyPair, *algo.ECDSAKeyPair, or *algo.Ed25519KeyPair)

Parameters:

  • privateKeyPEM: PEM-encoded private key data

Returns a new KeyPairManager instance or an error if parsing fails.

Example:

manager, err := LoadFromPEMData[*algo.RSAKeyPair](pemData)
if err != nil {
	log.Printf("Failed to load key pair: %v", err)
}

func LoadFromSSH

func LoadFromSSH[K KeyPair, P PrivateKey, B PublicKey](privateKeyFile string, passphrase string) (*Manager[K, P, B], error)

LoadFromSSH creates a new KeyPairManager by loading a private key from an SSH file. The public key is automatically derived from the private key.

Type parameter:

  • K: KeyPair type (*algo.RSAKeyPair, *algo.ECDSAKeyPair, or *algo.Ed25519KeyPair)

Parameters:

  • privateKeyFile: Path to the SSH-encoded private key file
  • passphrase: Passphrase for encrypted private keys (empty string for unencrypted)

Returns a new KeyPairManager instance or an error if loading fails.

Example:

manager, err := LoadFromSSH[*algo.Ed25519KeyPair]("id_ed25519", "passphrase")
if err != nil {
	log.Printf("Failed to load key pair: %v", err)
}

func LoadFromSSHData

func LoadFromSSHData[K KeyPair, P PrivateKey, B PublicKey](privateKeySSH format.SSH, passphrase string) (*Manager[K, P, B], error)

LoadFromSSHData creates a new KeyPairManager by parsing private key data in SSH format. The public key is automatically derived from the private key.

Type parameter:

  • K: KeyPair type (*algo.RSAKeyPair, *algo.ECDSAKeyPair, or *algo.Ed25519KeyPair)

Parameters:

  • privateKeySSH: SSH-encoded private key data
  • passphrase: Passphrase for encrypted private keys (empty string for unencrypted)

Returns a new KeyPairManager instance or an error if parsing fails.

Example:

manager, err := LoadFromSSHData[*algo.Ed25519KeyPair](sshData, "passphrase")
if err != nil {
	log.Printf("Failed to load key pair: %v", err)
}

func NewManager

func NewManager[K KeyPair, P PrivateKey, B PublicKey](keyPair K, privateKey P, publicKey B) *Manager[K, P, B]

NewManager creates a new KeyPairManager instance from an existing key pair. This constructor wraps an existing key pair to provide the manager's functionality.

Type parameter:

  • K: KeyPair type (*algo.RSAKeyPair, *algo.ECDSAKeyPair, or *algo.Ed25519KeyPair)

Parameters:

  • keyPair: The key pair to wrap in the manager

Returns a new KeyPairManager instance.

Example:

rsaKeyPair, _ := algo.GenerateRSAKeyPair(algo.KeySize2048)
manager := NewManager(rsaKeyPair)

func (*Manager[K, P, B]) Clone

func (m *Manager[K, P, B]) Clone() *Manager[K, P, B]

Clone creates a new KeyPairManager with the same key pair. This method creates a shallow copy of the KeyPairManager, sharing the same underlying key pair data.

Returns:

  • *KeyPairManager[K]: A new KeyPairManager instance with the same key pair

Note: This creates a shallow copy. The underlying cryptographic keys are shared between instances. If you need a deep copy with new cryptographic material, generate a new key pair instead.

Example:

clonedManager := manager.Clone()
// clonedManager and manager share the same key pair data

func (*Manager[K, P, B]) ComparePrivateKeys

func (m *Manager[K, P, B]) ComparePrivateKeys(other *Manager[K, P, B]) bool

ComparePrivateKeys compares only the private keys of two key managers. This method determines if the private keys are mathematically identical.

Parameters:

  • other: Another KeyPairManager to compare private keys with

Returns:

  • bool: true if private keys are identical, false otherwise

Example:

arePrivateKeysEqual := manager1.ComparePrivateKeys(manager2)

func (*Manager[K, P, B]) ComparePublicKeys

func (m *Manager[K, P, B]) ComparePublicKeys(other *Manager[K, P, B]) bool

ComparePublicKeys compares only the public keys of two key managers. This method determines if the public keys are mathematically identical.

Parameters:

  • other: Another KeyPairManager to compare public keys with

Returns:

  • bool: true if public keys are identical, false otherwise

Example:

arePublicKeysEqual := manager1.ComparePublicKeys(manager2)

func (*Manager[K, P, B]) CompareWith

func (m *Manager[K, P, B]) CompareWith(other *Manager[K, P, B]) bool

CompareWith compares two key managers for mathematical equality. This method compares both the private and public keys to determine if they are identical.

Parameters:

  • other: Another KeyPairManager to compare with

Returns:

  • bool: true if both key pairs are mathematically identical, false otherwise

Example:

isEqual := manager1.CompareWith(manager2)
if isEqual {
	fmt.Println("Key pairs are identical")
}

func (*Manager[K, P, B]) GetInfo

func (m *Manager[K, P, B]) GetInfo() (KeyInfo, error)

GetInfo returns metadata about the managed key pair. This includes algorithm type, key size, and curve information for ECDSA keys.

Returns KeyInfo struct with algorithm details or an error if analysis fails.

Example:

info, err := manager.GetInfo()
if err != nil {
	log.Printf("Failed to get key info: %v", err)
}
fmt.Printf("Algorithm: %s, KeySize: %d", info.Algorithm, info.KeySize)

func (*Manager[K, P, B]) IsValid

func (m *Manager[K, P, B]) IsValid() bool

IsValid checks if the KeyPairManager is properly initialized. This method verifies that the KeyPairManager contains a valid key pair.

Returns:

  • bool: true if the manager is initialized with a valid key pair, false otherwise

This method checks:

  • KeyPairManager is not nil
  • Key pair is not nil
  • Key pair contains valid private and public keys

Example:

if manager.IsValid() {
	fmt.Println("Manager is ready to use")
} else {
	fmt.Println("Manager is not properly initialized")
}

func (*Manager[K, P, B]) KeyPair

func (m *Manager[K, P, B]) KeyPair() K

KeyPair returns the underlying key pair managed by this instance.

Returns the key pair of type K.

Example:

keyPair := manager.KeyPair()

func (*Manager[K, P, B]) PrivateKey

func (m *Manager[K, P, B]) PrivateKey() P

PrivateKey extracts the private key from the managed key pair. The returned type is determined by the key pair type and returned as interface{}. Use type assertion to convert to the specific key type you need.

Returns the private key as interface{} or nil if extraction fails.

Example:

privateKey := manager.PrivateKey()
if rsaKey, ok := privateKey.(*rsa.PrivateKey); ok {
	// Use RSA private key
}

func (*Manager[K, P, B]) PublicKey

func (m *Manager[K, P, B]) PublicKey() B

PublicKey extracts the public key from the managed key pair. The returned type is determined by the key pair type and returned as interface{}. Use type assertion to convert to the specific key type you need.

Returns the public key as interface{} or nil if extraction fails.

Example:

publicKey := manager.PublicKey()
if rsaKey, ok := publicKey.(*rsa.PublicKey); ok {
	// Use RSA public key
}

func (*Manager[K, P, B]) SaveToDER

func (m *Manager[K, P, B]) SaveToDER(privateFile, publicFile string) error

SaveToDER saves the managed key pair to separate DER files. This method provides a convenient way to save both keys to files in DER format.

Parameters:

  • privateFile: Path where the private key will be saved
  • publicFile: Path where the public key will be saved

File permissions:

  • Private key files: 0600 (readable/writable by owner only)
  • Public key files: 0600 (for consistency)
  • Directories: 0700 (accessible by owner only)

Example:

err := manager.SaveToDER("private.der", "public.der")
if err != nil {
	log.Printf("Failed to save key pair: %v", err)
}

func (*Manager[K, P, B]) SaveToPEM

func (m *Manager[K, P, B]) SaveToPEM(privateFile, publicFile string) error

SaveToPEM saves the managed key pair to separate PEM files. This method provides a convenient way to save both keys to files in PEM format.

Parameters:

  • privateFile: Path where the private key will be saved
  • publicFile: Path where the public key will be saved

File permissions:

  • Private key files: 0600 (readable/writable by owner only)
  • Public key files: 0600 (for consistency)
  • Directories: 0700 (accessible by owner only)

Example:

err := manager.SaveToPEM("private.pem", "public.pem")
if err != nil {
	log.Printf("Failed to save key pair: %v", err)
}

func (*Manager[K, P, B]) SaveToSSH

func (m *Manager[K, P, B]) SaveToSSH(privateFile, publicFile string, comment, passphrase string) error

SaveToSSH saves the managed key pair to separate SSH files. This method provides a convenient way to save both keys to files in SSH format.

Parameters:

  • privateFile: Path where the private key will be saved
  • publicFile: Path where the public key will be saved
  • comment: Optional comment to include in the SSH keys (commonly username@hostname)
  • passphrase: Optional passphrase for private key encryption (empty string for unencrypted)

File permissions:

  • Private key files: 0600 (readable/writable by owner only)
  • Public key files: 0600 (for consistency)
  • Directories: 0700 (accessible by owner only)

Example:

err := manager.SaveToSSH("id_rsa", "id_rsa.pub", "user@host", "passphrase")
if err != nil {
	log.Printf("Failed to save key pair: %v", err)
}

func (*Manager[K, P, B]) ToDER

func (m *Manager[K, P, B]) ToDER() (privateKey, publicKey format.DER, err error)

ToDER converts the managed key pair to DER format, returning both private and public keys. This method provides a convenient way to get both keys in DER format in a single call.

Returns:

  • privateKey: DER-encoded private key in PKCS#8 format
  • publicKey: DER-encoded public key in PKIX format
  • error: Error if conversion fails

Example:

privateDER, publicDER, err := manager.ToDER()
if err != nil {
	log.Printf("Failed to convert to DER: %v", err)
}

func (*Manager[K, P, B]) ToPEM

func (m *Manager[K, P, B]) ToPEM() (privateKey, publicKey format.PEM, err error)

ToPEM converts the managed key pair to PEM format, returning both private and public keys. This method provides a convenient way to get both keys in PEM format in a single call.

Returns:

  • privateKey: PEM-encoded private key in PKCS#8 format
  • publicKey: PEM-encoded public key in PKIX format
  • error: Error if conversion fails

Example:

privatePEM, publicPEM, err := manager.ToPEM()
if err != nil {
	log.Printf("Failed to convert to PEM: %v", err)
}

func (*Manager[K, P, B]) ToSSH

func (m *Manager[K, P, B]) ToSSH(comment, passphrase string) (privateKey, publicKey format.SSH, err error)

ToSSH converts the managed key pair to SSH format, returning both private and public keys. This method provides a convenient way to get both keys in SSH format in a single call.

Parameters:

  • comment: Optional comment to include in the SSH keys (commonly username@hostname)
  • passphrase: Optional passphrase for private key encryption (empty string for unencrypted)

Returns:

  • privateKey: SSH-encoded private key in OpenSSH format
  • publicKey: SSH-encoded public key in authorized_keys format
  • error: Error if conversion fails

Example:

privateSSH, publicSSH, err := manager.ToSSH("user@host", "passphrase")
if err != nil {
	log.Printf("Failed to convert to SSH: %v", err)
}

func (*Manager[K, P, B]) Validate

func (m *Manager[K, P, B]) Validate() error

Validate verifies the mathematical relationship between the private and public keys. This ensures the key pair is valid and the public key correctly derives from the private key.

Returns nil if the key pair is valid, or an error describing the validation failure.

Example:

err := manager.Validate()
if err != nil {
	log.Printf("Key pair validation failed: %v", err)
}

func (*Manager[K, P, B]) ValidatePrivateKey

func (m *Manager[K, P, B]) ValidatePrivateKey() error

ValidatePrivateKey checks the validity and security standards of the private key. This includes verifying key size meets minimum security requirements.

Returns nil if the private key is valid and secure, or an error describing the issue.

Example:

err := manager.ValidatePrivateKey()
if err != nil {
	log.Printf("Private key validation failed: %v", err)
}

type Param

type Param interface {
	algo.KeySize | algo.ECDSACurve | algo.Ed25519Config
}

Param defines the constraint for key generation parameters. It accepts KeySize for RSA, ECDSACurve for ECDSA, or Ed25519Config for Ed25519.

type PrivateKey

type PrivateKey interface {
	*rsa.PrivateKey | *ecdsa.PrivateKey | ed25519.PrivateKey
}

PrivateKey defines the constraint for private key types. It accepts pointers to RSA/ECDSA private keys or Ed25519 private key values.

type PublicKey

type PublicKey interface {
	*rsa.PublicKey | *ecdsa.PublicKey | ed25519.PublicKey
}

PublicKey defines the constraint for public key types. It accepts pointers to RSA/ECDSA public keys or Ed25519 public key values.

Directories

Path Synopsis
Package algo provides algorithm-specific implementations for cryptographic key pair generation.
Package algo provides algorithm-specific implementations for cryptographic key pair generation.
Package format defines types for cryptographic key encoding formats.
Package format defines types for cryptographic key encoding formats.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL