This document describes the security features and hardening implemented in the go-as4 library.
The go-as4 library implements comprehensive security measures to protect AS4 message exchanges, including:
- Pluggable Certificate Validation - Flexible certificate validation supporting both traditional PKI and modern trust frameworks
- Cryptographic Input Validation - Comprehensive validation of all cryptographic inputs to prevent weak keys and attacks
- Secure Random Generation - Explicit use of cryptographically secure randomness throughout
- Size Limits and DoS Protection - Configurable limits to prevent resource exhaustion attacks
Certificate validation is implemented through a pluggable interface (CertificateValidator) that allows different trust models:
type CertificateValidator interface {
ValidateCertificate(cert *x509.Certificate, chain []*x509.Certificate, purpose string) error
ValidateCertificateChain(cert *x509.Certificate, intermediates []*x509.Certificate, purpose string) error
}Traditional X.509 PKI validation with:
- CA trust pool verification
- Certificate expiration checking
- Key usage validation
- Basic constraints verification
Usage:
validator := security.NewDefaultCertificateValidator(caCertPool)
signer.WithCertificateValidator(validator)Modern decentralized trust based on draft-johansson-authzen-trust:
- REST API-based trust decisions via Policy Decision Point (PDP)
- Supports multiple trust registries (ETSI, OpenID Federation, ledgers)
- Name-to-key binding validation
- Purpose-specific trust decisions
- Decentralized trust management
See docs/AUTHZEN.md for complete specification and examples.
Usage:
// Default action is "signing" - appropriate for AS4 XML signatures
validator := security.NewAuthZENTrustValidator("https://trust-pdp.example.com/evaluation")
signer.WithCertificateValidator(validator)
// For other use cases, configure the action:
validator.WithDefaultAction("tls-server") // TLS server certificates
validator.WithDefaultAction("encryption") // Encryption certificatesProtocol Example:
Request to PDP (for AS4 signing):
{
"type": "authzen",
"request": {
"subject": {"type": "key", "id": "party@example.com"},
"resource": {"type": "x5c", "id": "party@example.com", "key": ["<base64-cert>"]},
"action": {"name": "signing"}
}
}Response from PDP:
{
"decision": true
}Certificate validation is integrated into XML signature verification:
// Create signer with certificate validation
signer, _ := security.NewXMLSigner(privateKey, cert)
signer.WithCertificateValidator(validator)
// Verification automatically validates certificates
valid, err := signer.VerifyEnvelope(signedXML)All cryptographic keys are validated before use:
// Validates public key size and detects weak keys (all-zero)
ValidateEd25519PublicKey(publicKey ed25519.PublicKey) error
// Validates private key size and detects weak keys
ValidateEd25519PrivateKey(privateKey ed25519.PrivateKey) error// Validates and detects small-order points
ValidateX25519PublicKey(publicKey *[32]byte) error
// Validates private key
ValidateX25519PrivateKey(privateKey *[32]byte) errorSmall-Order Point Protection:
The library detects and rejects the following weak Curve25519 points:
- Point at infinity (all zeros)
- Order 2 point:
0xecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f - Order 4 points
- Order 8 points
// Validates AES key size (16, 24, or 32 bytes) and detects weak keys
ValidateAESKey(key []byte) error// Validates nonce size
ValidateNonce(nonce []byte, expectedSize int) error
// Validates ECDH shared secret (detects all-zero failures)
ValidateSharedSecret(secret *[32]byte) errorConfigurable limits prevent DoS attacks:
const (
MaxMessageSize = 10 * 1024 * 1024 // 10 MB
MaxAttachmentSize = 100 * 1024 * 1024 // 100 MB
MaxXMLDepth = 100
MaxCertificateSize = 64 * 1024 // 64 KB
)
// Validates input size and prevents null byte injection
SanitizeInputSize(data []byte, maxSize int, context string) error
ValidateInputData(data []byte, maxSize int, context string) errorInput validation is integrated throughout the encryption and signing operations:
// Encryption automatically validates all inputs
func (e *AESEncryptor) Encrypt(plaintext []byte) (ciphertext, ephemeralPublicKey, nonce []byte, err error) {
// Validates recipient public key
if err := ValidateX25519PublicKey(&e.recipientPublicKey); err != nil {
return nil, nil, nil, fmt.Errorf("invalid recipient public key: %w", err)
}
// Validates plaintext size
if err := SanitizeInputSize(plaintext, MaxMessageSize, "plaintext"); err != nil {
return nil, nil, nil, err
}
// ... encryption continues
}All cryptographic randomness uses crypto/rand.Reader explicitly:
// Ed25519 key generation
pub, priv, err := ed25519.GenerateKey(rand.Reader)
// Ephemeral key generation
if _, err := rand.Read(ephemeralPrivate[:]); err != nil {
return nil, nil, nil, fmt.Errorf("failed to generate ephemeral key: %w", err)
}
// Nonce generation
if _, err := io.ReadFull(rand.Reader, nonceData); err != nil {
return nil, nil, nil, fmt.Errorf("failed to generate nonce: %w", err)
}AES Key Wrap is implemented with full validation:
// Validates both KEK and key to wrap
func WrapKey(kek, keyToWrap []byte) ([]byte, error) {
if err := ValidateAESKey(kek); err != nil {
return nil, fmt.Errorf("invalid KEK: %w", err)
}
if err := ValidateAESKey(keyToWrap); err != nil {
return nil, fmt.Errorf("invalid key to wrap: %w", err)
}
// ... wrapping continues
}
// Validates unwrapped key
func UnwrapKey(kek, wrappedKey []byte) ([]byte, error) {
// ... unwrapping ...
if err := ValidateAESKey(plainKey); err != nil {
return nil, fmt.Errorf("invalid unwrapped key: %w", err)
}
return plainKey, nil
}-
Always configure certificate validation
validator := security.NewDefaultCertificateValidator(caCertPool) signer.WithCertificateValidator(validator)
-
Use appropriate trust levels for AuthZEN
// Require high trust level for signing operations validator := security.NewAuthZENTrustValidator(trustStore, 80)
-
Configure size limits appropriately
// Adjust MaxMessageSize based on your use case const MaxMessageSize = 5 * 1024 * 1024 // 5 MB for smaller messages
-
Monitor for validation failures
if err := validator.ValidateCertificate(cert, chain, "signing"); err != nil { // Log security event log.Error("Certificate validation failed", "error", err) return err }
-
Certificate Revocation: The current implementation does not check OCSP or CRL. This should be added for production use.
-
Nonce Tracking: GCM nonce reuse prevention is not yet implemented. Callers must ensure nonces are never reused.
-
Rate Limiting: No rate limiting is implemented. Applications should implement this at the transport layer.
-
Audit Logging: Security events are not automatically logged. Applications should implement audit logging.
This implementation addresses the following security vulnerabilities identified in the security audit:
- ✅ Missing certificate validation in
VerifySOAPMessage()- Now validates certificates when validator is configured - ✅ Weak random seed (nil reader) - All key generation uses explicit
rand.Reader - ✅ Missing input validation - Comprehensive validation for all cryptographic inputs
⚠️ No TLS certificate verification configuration - Applications must configure TLS at transport layer- ⏳ No protection against nonce reuse - Needs implementation
⚠️ Error information leakage - Errors are descriptive but don't leak sensitive data- ⏳ No rate limiting - Must be implemented at application layer
- ✅ Missing size validation - DoS protection implemented with configurable limits
⚠️ Potential timing attacks - Constant-time operations used where possible- ⏳ No certificate revocation checking - OCSP/CRL support needed
⚠️ Weak ID generation - Uses crypto/rand but could use UUIDs⚠️ Potential canonicalization attacks - Uses standard C14N, needs review
- ⏳ Incomplete security configuration - Applications should review all settings
- ⏳ Missing audit logging - Applications should implement
- ⏳ No key rotation mechanism - Applications should implement
- ⏳ TODO/placeholder security code - Under active development
- OCSP/CRL Support: Add certificate revocation checking
- Nonce Management: Implement nonce tracking for GCM
- Rate Limiting: Add configurable rate limiting
- Audit Logging: Implement security event logging framework
- Key Rotation: Add key rotation support
- Timing Attack Protection: Review and harden timing-sensitive operations