Documentation
¶
Overview ¶
Package kalkan provides an application-level Go API for KalkanCrypt.
The package supports hashing, CMS signatures, XML signatures, WS-Security signing, KalkanCrypt ZIP containers, certificate loading, and certificate validation. Inputs are described with typed request structs and Source values, so callers can choose in-memory data or native file paths without passing native KalkanCrypt flags through application code.
KalkanCrypt keeps process-global native state. Client serializes native calls inside the current process. Context cancellation can stop waiting to enter a native call, including waiting for the serialization lock, but it cannot interrupt a KalkanCrypt call that has already entered the shared library. Server-side production services that need hard native-call deadlines should isolate KalkanCrypt outside this package, for example behind a worker process or process pool controlled by the application.
Open requires WithLibraryPath with an absolute path to the native KalkanCrypt shared library. Dependent native libraries should be loaded only from trusted, read-only deployment directories. Passwords passed as Go strings cannot be zeroized by this package.
Index ¶
- Constants
- Variables
- type CMS
- type CMSOutputFormat
- type CertificateFormat
- type CertificateInfo
- type CertificateInfoField
- type CertificateTimeCheck
- type CertificateType
- type CertificateValidation
- type CertificateValidationMode
- type Client
- func (c *Client) Close() error
- func (c *Client) GetCertFromCMS(ctx context.Context, cms Source) ([]*x509.Certificate, error)
- func (c *Client) GetCertFromXML(ctx context.Context, source Source) ([]*x509.Certificate, error)
- func (c *Client) GetSigAlgFromXML(ctx context.Context, source Source) (string, error)
- func (c *Client) GetTimeFromSig(ctx context.Context, signature Source) (time.Time, error)
- func (c *Client) Hash(ctx context.Context, req HashRequest) (*Digest, error)
- func (c *Client) LoadKeyStore(ctx context.Context, store KeyStore) error
- func (c *Client) LoadTrustedCertificate(ctx context.Context, cert TrustedCertificate) error
- func (c *Client) SetProxy(ctx context.Context, proxy Proxy) error
- func (c *Client) SignCMS(ctx context.Context, req SignCMSRequest) (*CMS, error)
- func (c *Client) SignHash(ctx context.Context, req SignHashRequest) (*CMS, error)
- func (c *Client) SignWSSE(ctx context.Context, req SignWSSERequest) (*SignedXML, error)
- func (c *Client) SignXML(ctx context.Context, req SignXMLRequest) (*SignedXML, error)
- func (c *Client) SignZIP(ctx context.Context, req SignZIPRequest) (*SignedZIP, error)
- func (c *Client) ValidateCertificate(ctx context.Context, req ValidateCertificateRequest) (*CertificateValidation, error)
- func (c *Client) VerifyCMS(ctx context.Context, req VerifyCMSRequest) (*Verification, error)
- func (c *Client) VerifyXML(ctx context.Context, req VerifyXMLRequest) (*Verification, error)
- func (c *Client) VerifyZIP(ctx context.Context, req VerifyZIPRequest) (*ZIPVerification, error)
- func (c *Client) X509CertificateGetInfo(ctx context.Context, cert *x509.Certificate) (*CertificateInfo, error)
- func (c *Client) X509CertificateGetInfoFields(ctx context.Context, cert *x509.Certificate, fields CertificateInfoField) (*CertificateInfo, error)
- func (c *Client) X509ExportCertificateFromStore(ctx context.Context) (*x509.Certificate, error)
- func (c *Client) ZIPSignerCertificate(ctx context.Context, req ZIPSignerCertificateRequest) ([]byte, error)
- type Digest
- type Encoding
- type Environment
- type HashAlgorithm
- type HashRequest
- type KeyStore
- type KeyStoreType
- type Option
- func WithEnvironment(environment Environment) Option
- func WithLibraryPath(path string) Option
- func WithLogger(logger *slog.Logger) Option
- func WithMaxInputSize(size int64) Option
- func WithMaxOutputBufferSize(size int) Option
- func WithOCSPURL(url string) Option
- func WithProxy(proxy Proxy) Option
- func WithTSAURL(url string) Option
- func WithTrustedCertificate(cert TrustedCertificate) Option
- type Proxy
- type SignCMSRequest
- type SignHashRequest
- type SignWSSERequest
- type SignXMLRequest
- type SignZIPRequest
- type SignedXML
- type SignedZIP
- type Source
- type TrustedCertificate
- type ValidateCertificateRequest
- type Verification
- type VerifyCMSRequest
- type VerifyXMLRequest
- type VerifyZIPRequest
- type XMLCanonicalization
- type ZIPSignerCertificateRequest
- type ZIPVerification
Examples ¶
Constants ¶
const CertificateInfoAllFields = CertificateInfoSubject | CertificateInfoSerialNumber | CertificateInfoValidFrom | CertificateInfoValidUntil | CertificateInfoIssuer | CertificateInfoPolicy | CertificateInfoKeyUsage | CertificateInfoExtKeyUsage | CertificateInfoAuthKeyID | CertificateInfoSubjKeyID | CertificateInfoAlgorithmSignCert | CertificateInfoPublicKey | CertificateInfoOCSPURL | CertificateInfoCRLURL | CertificateInfoDeltaCRLURL
CertificateInfoAllFields requests the same properties as X509CertificateGetInfo.
Variables ¶
var ( // ErrInvalidInput is wrapped by validation errors raised before native calls. ErrInvalidInput = errors.New("kalkan: invalid input") // ErrClosed is returned when a Client method is called after Close. ErrClosed = errors.New("kalkan: client is closed") // unavailable for the current build/platform. ErrUnavailable = errors.New("kalkan: native KalkanCrypt loader is unavailable") )
Functions ¶
This section is empty.
Types ¶
type CMS ¶
type CMS struct {
// Data contains CMS output bytes. By default this is raw DER CMS; when a
// signing request sets OutputFormat, Data contains native base64 or PEM
// text bytes instead.
Data []byte
}
CMS is a CMS signature returned by SignCMS.
type CMSOutputFormat ¶
type CMSOutputFormat int
CMSOutputFormat selects the representation returned by CMS signing operations.
const ( // CMSOutputDER returns raw binary ASN.1 DER CMS bytes. This is the default // output format and can be passed back to VerifyCMS using Bytes or DER // sources. CMSOutputDER CMSOutputFormat = iota // CMSOutputBase64 returns base64 text for the DER CMS bytes, without PEM // header/footer armor. Use it for text-only transports or JSON fields. CMSOutputBase64 // CMSOutputPEM returns PEM-armored text: base64 DER plus header/footer and // line wrapping. Use it for copy/paste workflows and PEM-oriented tools. CMSOutputPEM )
type CertificateFormat ¶
type CertificateFormat int
CertificateFormat identifies certificate byte encoding.
const ( // CertificateDER is DER binary certificate data. CertificateDER CertificateFormat = iota // CertificatePEM is PEM text certificate data. CertificatePEM // CertificateBase64 is base64 certificate data. CertificateBase64 )
type CertificateInfo ¶
type CertificateInfo struct {
// Subject is the native subject distinguished name string.
Subject string
// SerialNumber is the native certificate serial number string.
SerialNumber string
// ValidFrom is the parsed native notBefore value.
ValidFrom time.Time
// ValidUntil is the parsed native notAfter value.
ValidUntil time.Time
// Issuer is the native issuer distinguished name string.
Issuer string
// Policy is the native certificate policies string.
Policy string
// KeyUsage is the native key usage string.
KeyUsage string
// ExtKeyUsage is the native extended key usage string.
ExtKeyUsage string
// AuthKeyID is the native authority key identifier string.
AuthKeyID string
// SubjKeyID is the native subject key identifier string.
SubjKeyID string
// AlgorithmSignCert is the native certificate signature algorithm string.
AlgorithmSignCert string
// PublicKey is the native public key string.
PublicKey string
// OCSPURL is the native OCSP responder string.
OCSPURL string
// CRLURL is the native CRL distribution point string.
CRLURL string
// DeltaCRLURL is the native delta CRL distribution point string.
DeltaCRLURL string
// Policies contains parsed values from Policy.
Policies []string
// KeyUsages contains parsed values from KeyUsage.
KeyUsages []string
// ExtKeyUsages contains parsed values from ExtKeyUsage.
ExtKeyUsages []string
}
CertificateInfo contains selected KalkanCrypt certificate properties.
type CertificateInfoField ¶
type CertificateInfoField uint64
CertificateInfoField selects certificate properties requested from KalkanCrypt. Use X509CertificateGetInfo for the full legacy set.
const ( // CertificateInfoSubject requests the native subject distinguished name. CertificateInfoSubject CertificateInfoField = 1 << iota // CertificateInfoSerialNumber requests the native serial number. CertificateInfoSerialNumber // CertificateInfoValidFrom requests the native notBefore value. CertificateInfoValidFrom // CertificateInfoValidUntil requests the native notAfter value. CertificateInfoValidUntil // CertificateInfoIssuer requests the native issuer distinguished name. CertificateInfoIssuer // CertificateInfoPolicy requests native certificate policy values. CertificateInfoPolicy // CertificateInfoKeyUsage requests native key usage values. CertificateInfoKeyUsage // CertificateInfoExtKeyUsage requests native extended key usage values. CertificateInfoExtKeyUsage // CertificateInfoAuthKeyID requests the authority key identifier. CertificateInfoAuthKeyID // CertificateInfoSubjKeyID requests the subject key identifier. CertificateInfoSubjKeyID // CertificateInfoAlgorithmSignCert requests the signature algorithm. CertificateInfoAlgorithmSignCert // CertificateInfoPublicKey requests the native public key string. CertificateInfoPublicKey // CertificateInfoOCSPURL requests the OCSP responder URL. CertificateInfoOCSPURL // CertificateInfoCRLURL requests the CRL distribution point URL. CertificateInfoCRLURL // CertificateInfoDeltaCRLURL requests the delta CRL distribution point URL. CertificateInfoDeltaCRLURL )
type CertificateTimeCheck ¶
type CertificateTimeCheck int
CertificateTimeCheck controls certificate-time checks performed by KalkanCrypt while verifying signatures or certificate chains.
const ( // DefaultCertificateTimeCheck keeps KalkanCrypt's default certificate-time // validation behavior. DefaultCertificateTimeCheck CertificateTimeCheck = iota // SkipCertificateTimeCheck sets KC_NOCHECKCERTTIME. It can be useful when // verifying signatures according to an external archival policy, but it // weakens validation and should be enabled only when that policy explicitly // allows it. SkipCertificateTimeCheck )
type CertificateType ¶
type CertificateType int
CertificateType identifies a certificate role in KalkanCrypt's store.
const ( // CertificateCA marks a root CA certificate. CertificateCA CertificateType = iota // CertificateIntermediate marks an intermediate CA certificate. CertificateIntermediate // CertificateUser marks a user certificate. CertificateUser )
type CertificateValidation ¶
type CertificateValidation struct {
// Valid is true when KalkanCrypt returned success.
Valid bool
// Info is KalkanCrypt's native validation information string.
Info string
// OCSPResponse contains the optional raw OCSP response returned by
// KalkanCrypt when ReturnOCSPResponse is set.
OCSPResponse []byte
}
CertificateValidation is returned by ValidateCertificate.
type CertificateValidationMode ¶
type CertificateValidationMode int
CertificateValidationMode selects how KalkanCrypt checks certificate revocation while validating a certificate.
const ( // CertificateValidationUnspecified is the zero value and is rejected by // ValidateCertificate. Select OCSP, CRL, or CertificateValidationNone // explicitly. CertificateValidationUnspecified CertificateValidationMode = iota // CertificateValidationNone disables external CRL/OCSP validation. CertificateValidationNone // CertificateValidationCRL validates against a CRL file or directory path. CertificateValidationCRL // CertificateValidationOCSP validates through an OCSP responder. CertificateValidationOCSP )
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client owns one initialized KalkanCrypt session.
KalkanCrypt stores process-global state inside the native library. The low-level ckalkan package therefore allows one active native client per process and serializes native calls. Client follows that model.
func Open ¶
Open loads and initializes KalkanCrypt.
The context is checked before and between Go setup steps and while waiting to enter a native call, including waiting for the native call serialization lock. It cannot interrupt a KalkanCrypt call after control has entered the shared library.
Example ¶
package main
import (
"context"
"log"
"os"
"github.com/skarm/kalkan"
)
func main() {
ctx := context.Background()
client, err := kalkan.Open(ctx,
kalkan.WithEnvironment(kalkan.TestEnvironment),
kalkan.WithLibraryPath("/usr/local/lib/libkalkancryptwr-64.so"),
kalkan.WithTrustedCertificate(kalkan.TrustedCertificate{
Path: "/etc/kalkan/certs/root.pem",
Type: kalkan.CertificateCA,
}),
)
if err != nil {
log.Fatal(err)
}
err = client.LoadKeyStore(ctx, kalkan.KeyStore{
Type: kalkan.PKCS12,
Path: "/etc/kalkan/keys/signing.p12",
Password: os.Getenv("KALKAN_KEY_PASSWORD"),
Alias: "signing-key",
})
if err != nil {
_ = client.Close()
log.Fatal(err)
}
defer client.Close()
}
Output:
func (*Client) Close ¶
Close releases the native KalkanCrypt session. It may be called more than once.
func (*Client) GetCertFromCMS ¶
GetCertFromCMS extracts signer certificates embedded in a CMS container.
func (*Client) GetCertFromXML ¶
GetCertFromXML extracts signer certificates embedded in signed XML.
func (*Client) GetSigAlgFromXML ¶
GetSigAlgFromXML returns the native XML signature algorithm identifier.
func (*Client) GetTimeFromSig ¶
GetTimeFromSig returns the timestamp embedded in a CMS signature.
func (*Client) Hash ¶
Hash calculates a digest using KalkanCrypt.
Example ¶
package main
import (
"context"
"log"
"os"
"github.com/skarm/kalkan"
)
func main() {
ctx := context.Background()
client := openExampleClient(ctx)
digest, err := client.Hash(ctx, kalkan.HashRequest{
Algorithm: kalkan.GOST2015_512,
Data: kalkan.File("/data/document.bin"),
})
if err != nil {
_ = client.Close()
log.Fatal(err)
}
defer client.Close()
_ = digest.Data
}
func openExampleClient(ctx context.Context) *kalkan.Client {
client, err := kalkan.Open(ctx,
kalkan.WithEnvironment(kalkan.TestEnvironment),
kalkan.WithLibraryPath("/usr/local/lib/libkalkancryptwr-64.so"),
)
if err != nil {
log.Fatal(err)
}
if err := client.LoadKeyStore(ctx, kalkan.KeyStore{
Type: kalkan.PKCS12,
Path: "/etc/kalkan/keys/signing.p12",
Password: os.Getenv("KALKAN_KEY_PASSWORD"),
Alias: "signing-key",
}); err != nil {
_ = client.Close()
log.Fatal(err)
}
return client
}
Output:
func (*Client) LoadKeyStore ¶
LoadKeyStore loads a key container into the native KalkanCrypt session.
func (*Client) LoadTrustedCertificate ¶
func (c *Client) LoadTrustedCertificate(ctx context.Context, cert TrustedCertificate) error
LoadTrustedCertificate loads a certificate into the native KalkanCrypt store.
func (*Client) SignCMS ¶
SignCMS signs data and returns CMS output bytes. The default output format is raw DER CMS.
Example ¶
package main
import (
"context"
"log"
"os"
"github.com/skarm/kalkan"
)
func main() {
ctx := context.Background()
client := openExampleClient(ctx)
signed, err := client.SignCMS(ctx, kalkan.SignCMSRequest{
Data: kalkan.Bytes([]byte("document payload")),
Detached: true,
Timestamp: true,
IncludeCertificate: true,
})
if err != nil {
_ = client.Close()
log.Fatal(err)
}
defer client.Close()
_ = signed.Data
}
func openExampleClient(ctx context.Context) *kalkan.Client {
client, err := kalkan.Open(ctx,
kalkan.WithEnvironment(kalkan.TestEnvironment),
kalkan.WithLibraryPath("/usr/local/lib/libkalkancryptwr-64.so"),
)
if err != nil {
log.Fatal(err)
}
if err := client.LoadKeyStore(ctx, kalkan.KeyStore{
Type: kalkan.PKCS12,
Path: "/etc/kalkan/keys/signing.p12",
Password: os.Getenv("KALKAN_KEY_PASSWORD"),
Alias: "signing-key",
}); err != nil {
_ = client.Close()
log.Fatal(err)
}
return client
}
Output:
func (*Client) SignHash ¶
SignHash signs raw digest bytes and returns CMS output bytes. The default output format is raw DER CMS.
Example ¶
package main
import (
"context"
"log"
"os"
"github.com/skarm/kalkan"
)
func main() {
ctx := context.Background()
client := openExampleClient(ctx)
digest, err := client.Hash(ctx, kalkan.HashRequest{
Algorithm: kalkan.GOST2015_512,
Data: kalkan.Bytes([]byte("document payload")),
})
if err != nil {
_ = client.Close()
log.Fatal(err)
}
signed, err := client.SignHash(ctx, kalkan.SignHashRequest{
Digest: digest.Data,
DigestAlgorithm: digest.Algorithm,
IncludeCertificate: true,
})
if err != nil {
_ = client.Close()
log.Fatal(err)
}
defer client.Close()
_ = signed.Data
}
func openExampleClient(ctx context.Context) *kalkan.Client {
client, err := kalkan.Open(ctx,
kalkan.WithEnvironment(kalkan.TestEnvironment),
kalkan.WithLibraryPath("/usr/local/lib/libkalkancryptwr-64.so"),
)
if err != nil {
log.Fatal(err)
}
if err := client.LoadKeyStore(ctx, kalkan.KeyStore{
Type: kalkan.PKCS12,
Path: "/etc/kalkan/keys/signing.p12",
Password: os.Getenv("KALKAN_KEY_PASSWORD"),
Alias: "signing-key",
}); err != nil {
_ = client.Close()
log.Fatal(err)
}
return client
}
Output:
func (*Client) SignWSSE ¶
SignWSSE signs a SOAP/WS-Security document.
Example ¶
package main
import (
"context"
"log"
"os"
"github.com/skarm/kalkan"
)
func main() {
ctx := context.Background()
client := openExampleClient(ctx)
signed, err := client.SignWSSE(ctx, kalkan.SignWSSERequest{
XML: kalkan.Bytes([]byte(`<m:GetData xmlns:m="urn:example"/>`)),
BodyID: "TheBody",
WrapSOAP: true,
Canonicalization: kalkan.XMLCanonicalizationInclusive,
})
if err != nil {
_ = client.Close()
log.Fatal(err)
}
defer client.Close()
_ = signed.XML
}
func openExampleClient(ctx context.Context) *kalkan.Client {
client, err := kalkan.Open(ctx,
kalkan.WithEnvironment(kalkan.TestEnvironment),
kalkan.WithLibraryPath("/usr/local/lib/libkalkancryptwr-64.so"),
)
if err != nil {
log.Fatal(err)
}
if err := client.LoadKeyStore(ctx, kalkan.KeyStore{
Type: kalkan.PKCS12,
Path: "/etc/kalkan/keys/signing.p12",
Password: os.Getenv("KALKAN_KEY_PASSWORD"),
Alias: "signing-key",
}); err != nil {
_ = client.Close()
log.Fatal(err)
}
return client
}
Output:
func (*Client) SignXML ¶
SignXML signs an XML document.
Example ¶
package main
import (
"context"
"log"
"os"
"github.com/skarm/kalkan"
)
func main() {
ctx := context.Background()
client := openExampleClient(ctx)
signed, err := client.SignXML(ctx, kalkan.SignXMLRequest{
XML: kalkan.Bytes([]byte(`<root><value>data</value></root>`)),
Canonicalization: kalkan.XMLCanonicalizationInclusive,
})
if err != nil {
_ = client.Close()
log.Fatal(err)
}
defer client.Close()
_ = signed.XML
}
func openExampleClient(ctx context.Context) *kalkan.Client {
client, err := kalkan.Open(ctx,
kalkan.WithEnvironment(kalkan.TestEnvironment),
kalkan.WithLibraryPath("/usr/local/lib/libkalkancryptwr-64.so"),
)
if err != nil {
log.Fatal(err)
}
if err := client.LoadKeyStore(ctx, kalkan.KeyStore{
Type: kalkan.PKCS12,
Path: "/etc/kalkan/keys/signing.p12",
Password: os.Getenv("KALKAN_KEY_PASSWORD"),
Alias: "signing-key",
}); err != nil {
_ = client.Close()
log.Fatal(err)
}
return client
}
Output:
func (*Client) SignZIP ¶
SignZIP signs InputPath and creates a KalkanCrypt ZIP container at OutputPath.
Example ¶
package main
import (
"context"
"log"
"os"
"path/filepath"
"github.com/skarm/kalkan"
)
func main() {
ctx := context.Background()
client := openExampleClient(ctx)
outputDir, err := os.MkdirTemp("", "kalkan-signzip-*")
if err != nil {
_ = client.Close()
log.Fatal(err)
}
cleanupOutputDir := func() {
_ = os.RemoveAll(outputDir)
}
if err := os.Chmod(outputDir, 0o700); err != nil {
cleanupOutputDir()
_ = client.Close()
log.Fatal(err)
}
signed, err := client.SignZIP(ctx, kalkan.SignZIPRequest{
InputPath: "/data/document.bin",
OutputPath: filepath.Join(outputDir, "document.signed.zip"),
})
if err != nil {
cleanupOutputDir()
_ = client.Close()
log.Fatal(err)
}
defer cleanupOutputDir()
defer client.Close()
_ = signed.Path
}
func openExampleClient(ctx context.Context) *kalkan.Client {
client, err := kalkan.Open(ctx,
kalkan.WithEnvironment(kalkan.TestEnvironment),
kalkan.WithLibraryPath("/usr/local/lib/libkalkancryptwr-64.so"),
)
if err != nil {
log.Fatal(err)
}
if err := client.LoadKeyStore(ctx, kalkan.KeyStore{
Type: kalkan.PKCS12,
Path: "/etc/kalkan/keys/signing.p12",
Password: os.Getenv("KALKAN_KEY_PASSWORD"),
Alias: "signing-key",
}); err != nil {
_ = client.Close()
log.Fatal(err)
}
return client
}
Output:
func (*Client) ValidateCertificate ¶
func (c *Client) ValidateCertificate(ctx context.Context, req ValidateCertificateRequest) (*CertificateValidation, error)
ValidateCertificate validates a certificate through KalkanCrypt.
Example ¶
package main
import (
"context"
"log"
"os"
"github.com/skarm/kalkan"
)
func main() {
ctx := context.Background()
client := openExampleClient(ctx)
certPEM, err := os.ReadFile("/etc/kalkan/certs/user.pem")
if err != nil {
_ = client.Close()
log.Fatal(err)
}
validation, err := client.ValidateCertificate(ctx, kalkan.ValidateCertificateRequest{
Certificate: kalkan.PEM(certPEM),
Mode: kalkan.CertificateValidationOCSP,
ReturnOCSPResponse: true,
})
if err != nil {
_ = client.Close()
log.Fatal(err)
}
defer client.Close()
_ = validation.Valid
_ = validation.OCSPResponse
}
func openExampleClient(ctx context.Context) *kalkan.Client {
client, err := kalkan.Open(ctx,
kalkan.WithEnvironment(kalkan.TestEnvironment),
kalkan.WithLibraryPath("/usr/local/lib/libkalkancryptwr-64.so"),
)
if err != nil {
log.Fatal(err)
}
if err := client.LoadKeyStore(ctx, kalkan.KeyStore{
Type: kalkan.PKCS12,
Path: "/etc/kalkan/keys/signing.p12",
Password: os.Getenv("KALKAN_KEY_PASSWORD"),
Alias: "signing-key",
}); err != nil {
_ = client.Close()
log.Fatal(err)
}
return client
}
Output:
func (*Client) VerifyCMS ¶
func (c *Client) VerifyCMS(ctx context.Context, req VerifyCMSRequest) (*Verification, error)
VerifyCMS verifies an attached or detached CMS signature.
Example ¶
package main
import (
"context"
"log"
"os"
"github.com/skarm/kalkan"
)
func main() {
ctx := context.Background()
client := openExampleClient(ctx)
verification, err := client.VerifyCMS(ctx, kalkan.VerifyCMSRequest{
Signature: kalkan.File("/data/signature.cms").WithEncoding(kalkan.EncodingDER),
Data: kalkan.File("/data/document.bin"),
Detached: true,
})
if err != nil {
_ = client.Close()
log.Fatal(err)
}
defer client.Close()
_ = verification.Valid
_ = verification.SignerCert
}
func openExampleClient(ctx context.Context) *kalkan.Client {
client, err := kalkan.Open(ctx,
kalkan.WithEnvironment(kalkan.TestEnvironment),
kalkan.WithLibraryPath("/usr/local/lib/libkalkancryptwr-64.so"),
)
if err != nil {
log.Fatal(err)
}
if err := client.LoadKeyStore(ctx, kalkan.KeyStore{
Type: kalkan.PKCS12,
Path: "/etc/kalkan/keys/signing.p12",
Password: os.Getenv("KALKAN_KEY_PASSWORD"),
Alias: "signing-key",
}); err != nil {
_ = client.Close()
log.Fatal(err)
}
return client
}
Output:
func (*Client) VerifyXML ¶
func (c *Client) VerifyXML(ctx context.Context, req VerifyXMLRequest) (*Verification, error)
VerifyXML verifies a signed XML document.
func (*Client) VerifyZIP ¶
func (c *Client) VerifyZIP(ctx context.Context, req VerifyZIPRequest) (*ZIPVerification, error)
VerifyZIP verifies a KalkanCrypt ZIP container.
Example ¶
package main
import (
"context"
"log"
"os"
"github.com/skarm/kalkan"
)
func main() {
ctx := context.Background()
client := openExampleClient(ctx)
verification, err := client.VerifyZIP(ctx, kalkan.VerifyZIPRequest{
Path: "/data/document.signed.zip",
ReturnSignerCertificate: true,
})
if err != nil {
_ = client.Close()
log.Fatal(err)
}
defer client.Close()
_ = verification.Valid
_ = verification.SignerCert
}
func openExampleClient(ctx context.Context) *kalkan.Client {
client, err := kalkan.Open(ctx,
kalkan.WithEnvironment(kalkan.TestEnvironment),
kalkan.WithLibraryPath("/usr/local/lib/libkalkancryptwr-64.so"),
)
if err != nil {
log.Fatal(err)
}
if err := client.LoadKeyStore(ctx, kalkan.KeyStore{
Type: kalkan.PKCS12,
Path: "/etc/kalkan/keys/signing.p12",
Password: os.Getenv("KALKAN_KEY_PASSWORD"),
Alias: "signing-key",
}); err != nil {
_ = client.Close()
log.Fatal(err)
}
return client
}
Output:
func (*Client) X509CertificateGetInfo ¶
func (c *Client) X509CertificateGetInfo(ctx context.Context, cert *x509.Certificate) (*CertificateInfo, error)
X509CertificateGetInfo collects commonly used certificate properties through KalkanCrypt's native X509CertificateGetInfo calls.
func (*Client) X509CertificateGetInfoFields ¶
func (c *Client) X509CertificateGetInfoFields(ctx context.Context, cert *x509.Certificate, fields CertificateInfoField) (*CertificateInfo, error)
X509CertificateGetInfoFields collects selected certificate properties through KalkanCrypt's native X509CertificateGetInfo calls.
func (*Client) X509ExportCertificateFromStore ¶
X509ExportCertificateFromStore exports the default certificate from KalkanCrypt's native store and parses it as an x509 certificate.
func (*Client) ZIPSignerCertificate ¶
func (c *Client) ZIPSignerCertificate(ctx context.Context, req ZIPSignerCertificateRequest) ([]byte, error)
ZIPSignerCertificate extracts a signer certificate from a KalkanCrypt ZIP container.
type Digest ¶
type Digest struct {
// Algorithm is the algorithm used to calculate Data.
Algorithm HashAlgorithm
// Data contains the raw digest bytes.
Data []byte
}
Digest is returned by Hash.
type Encoding ¶
type Encoding int
Encoding describes how bytes or file contents are encoded before KalkanCrypt reads them.
const ( // EncodingAuto lets the operation choose the field-specific default. // For example, VerifyCMS treats raw CMS bytes as DER CMS input. EncodingAuto Encoding = iota // EncodingRaw means the source is plain binary/text data. Operations may // map raw data to the native flag that represents their raw format, such as // DER for CMS signatures. EncodingRaw // EncodingBase64 means the source is already base64 text. EncodingBase64 // EncodingPEM means the source is PEM text. EncodingPEM // EncodingDER means the source is DER binary data. EncodingDER )
type Environment ¶
type Environment int
Environment selects default KalkanCrypt network endpoints.
const ( // ProductionEnvironment configures production network defaults. ProductionEnvironment Environment = iota // TestEnvironment configures test network defaults. TestEnvironment )
type HashAlgorithm ¶
type HashAlgorithm int
HashAlgorithm selects the digest algorithm used by Hash.
const ( // SHA256 calculates a SHA-256 digest. SHA256 HashAlgorithm = iota // GOST95 calculates a GOST R 34.11-95 digest. GOST95 // GOST2015_256 calculates a GOST R 34.11-2015 256-bit digest. GOST2015_256 // GOST2015_512 calculates a GOST R 34.11-2015 512-bit digest. GOST2015_512 )
type HashRequest ¶
type HashRequest struct {
// Algorithm selects the digest algorithm. The zero value is SHA256.
Algorithm HashAlgorithm
// Data is the input data. File sources are passed to KalkanCrypt as file
// paths when the native library supports KC_IN_FILE for HashData.
Data Source
}
HashRequest describes data to hash.
type KeyStore ¶
type KeyStore struct {
// Type selects the storage provider.
Type KeyStoreType
// Path is the native container path.
Path string
// Password is the container password.
Password string
// Alias optionally selects a key alias inside the container.
Alias string
}
KeyStore describes a private-key container to load into KalkanCrypt.
type KeyStoreType ¶
type KeyStoreType int
KeyStoreType identifies a KalkanCrypt key storage provider.
const ( // PKCS12 loads a file-system PKCS#12 container. PKCS12 KeyStoreType = iota )
type Option ¶
type Option func(*config)
Option configures Open.
func WithEnvironment ¶
func WithEnvironment(environment Environment) Option
WithEnvironment selects production or test endpoint defaults.
func WithLibraryPath ¶
WithLibraryPath sets the absolute KalkanCrypt shared-library path.
func WithLogger ¶
WithLogger enables diagnostic structured logging for Client operations. Passing nil leaves logging disabled. The logger receives a component=kalkan attribute and is never installed as slog's process-global default logger.
func WithMaxInputSize ¶
WithMaxInputSize sets a byte limit for high-level in-memory byte inputs before native calls. Values less than or equal to zero leave memory inputs unlimited.
func WithMaxOutputBufferSize ¶
WithMaxOutputBufferSize sets the hard cap used by the low-level KalkanCrypt output-buffer retry policy. Values less than or equal to zero keep the low-level default. Very small positive values are normalized by ckalkan to its conservative minimum output buffer size.
func WithOCSPURL ¶
WithOCSPURL overrides the OCSP endpoint used by ValidateCertificate when the request does not specify RevocationSource.
func WithTSAURL ¶
WithTSAURL overrides the timestamp authority endpoint.
func WithTrustedCertificate ¶
func WithTrustedCertificate(cert TrustedCertificate) Option
WithTrustedCertificate loads a trusted certificate during Open.
type Proxy ¶
type Proxy struct {
// Enabled enables or disables proxy use.
Enabled bool
// Address is the proxy host or IP address.
Address string
// Port is the proxy port.
Port string
// User is the optional proxy username.
User string
// Password is the optional proxy password.
Password string
}
Proxy configures KalkanCrypt's native HTTP proxy.
type SignCMSRequest ¶
type SignCMSRequest struct {
// Alias selects a loaded key alias. Empty alias lets KalkanCrypt use its
// default loaded key when the native library supports that behavior.
Alias string
// Data is the payload to sign. The zero-value Source is rejected; use
// Bytes(nil) or Bytes([]byte{}) only when an explicit empty payload is
// intended.
Data Source
// Detached requests a detached CMS signature.
Detached bool
// Timestamp requests a TSA timestamp token.
Timestamp bool
// IncludeCertificate asks KalkanCrypt to embed the signing certificate in
// the CMS container.
IncludeCertificate bool
// OutputFormat selects the CMS output representation. The zero value
// returns raw DER CMS bytes.
OutputFormat CMSOutputFormat
// CertificateTimeCheck controls KalkanCrypt certificate-time validation while
// building the signature.
CertificateTimeCheck CertificateTimeCheck
}
SignCMSRequest describes CMS signing input.
type SignHashRequest ¶
type SignHashRequest struct {
// Alias selects a loaded key alias. Empty alias lets KalkanCrypt use its
// default loaded key when the native library supports that behavior.
Alias string
// Digest contains the precomputed raw digest bytes to sign, not the original
// payload.
Digest []byte
// DigestAlgorithm selects the algorithm that produced Digest. The zero value
// is SHA256. Set it explicitly when signing GOST or other non-SHA256 digests
// so the wrapper can reject length mismatches before native calls.
DigestAlgorithm HashAlgorithm
// Timestamp requests a TSA timestamp token.
Timestamp bool
// IncludeCertificate asks KalkanCrypt to embed the signing certificate in
// the CMS container.
IncludeCertificate bool
// OutputFormat selects the CMS output representation. The zero value
// returns raw DER CMS bytes.
OutputFormat CMSOutputFormat
// CertificateTimeCheck controls KalkanCrypt certificate-time validation while
// signing the digest.
CertificateTimeCheck CertificateTimeCheck
}
SignHashRequest describes signing of an already calculated digest.
type SignWSSERequest ¶
type SignWSSERequest struct {
// Alias selects a loaded key alias.
Alias string
// XML is either a full SOAP envelope or a payload that should be wrapped when
// WrapSOAP is true.
XML Source
// BodyID is the wsu:Id value of the SOAP Body that KalkanCrypt signs. It
// is required whether XML is wrapped by this package or supplied as a full
// SOAP envelope.
BodyID string
// WrapSOAP wraps XML into a minimal SOAP envelope before signing.
WrapSOAP bool
// Canonicalization selects the XML canonicalization algorithm.
Canonicalization XMLCanonicalization
// CertificateTimeCheck controls certificate-time validation.
CertificateTimeCheck CertificateTimeCheck
}
SignWSSERequest describes WS-Security XML signing input.
type SignXMLRequest ¶
type SignXMLRequest struct {
// Alias selects a loaded key alias.
Alias string
// XML is the XML document to sign.
XML Source
// SignNodeID is the XML node id passed to KalkanCrypt.
SignNodeID string
// ParentSignNode is the parent signature node name passed to KalkanCrypt.
ParentSignNode string
// ParentNamespace is the parent signature namespace passed to KalkanCrypt.
ParentNamespace string
// Canonicalization selects the XML canonicalization algorithm.
Canonicalization XMLCanonicalization
// CertificateTimeCheck controls certificate-time validation.
CertificateTimeCheck CertificateTimeCheck
}
SignXMLRequest describes XML signing input.
type SignZIPRequest ¶
type SignZIPRequest struct {
// Alias selects a loaded key alias. Empty alias lets KalkanCrypt use its
// default loaded key when the native library supports that behavior.
Alias string
// InputPath is the input file path passed to KalkanCrypt.
InputPath string
// OutputPath is the expected ZIP container path and must end with .zip,
// matched case-insensitively. KalkanCrypt creates lowercase .zip output, so
// non-lowercase extensions are accepted but SignedZIP.Path reports the
// actual lowercase path.
// Use a private service-controlled output directory: KalkanCrypt writes the
// output file itself, so this wrapper rejects a pre-existing output but
// cannot make the native create operation atomically exclusive.
OutputPath string
// CertificateTimeCheck controls KalkanCrypt certificate-time validation while
// building the ZIP signature.
CertificateTimeCheck CertificateTimeCheck
}
SignZIPRequest describes signing a file into a KalkanCrypt ZIP container.
type SignedXML ¶
type SignedXML struct {
// XML contains the signed XML document.
XML []byte
}
SignedXML is returned by SignXML and SignWSSE.
type SignedZIP ¶
type SignedZIP struct {
// Path is the ZIP container path created by KalkanCrypt.
Path string
}
SignedZIP is returned by SignZIP.
type Source ¶
type Source struct {
// contains filtered or unexported fields
}
Source is an operation input that can be either in-memory bytes or a file path. File sources allow KalkanCrypt to read large detached payloads directly when the native function supports KC_IN_FILE. The zero-value Source means "not provided"; constructor-created empty byte sources represent explicit empty input and are validated by each operation's own rules.
func Bytes ¶
Bytes returns an in-memory raw source. Use File for large payloads that KalkanCrypt should read directly.
func File ¶
File returns a file-path source. Empty paths and embedded NUL bytes are rejected by operations before native calls.
func (Source) WithEncoding ¶
WithEncoding returns a copy of the source with an explicit encoding.
type TrustedCertificate ¶
type TrustedCertificate struct {
// Data contains certificate bytes when Path is empty.
Data []byte
// Path is loaded directly by KalkanCrypt when set.
Path string
// Type selects CA, intermediate, or user certificate role.
Type CertificateType
// Format selects PEM, DER, or base64 bytes for Data.
Format CertificateFormat
}
TrustedCertificate describes a certificate loaded into KalkanCrypt's trust store.
type ValidateCertificateRequest ¶
type ValidateCertificateRequest struct {
// Certificate contains the certificate bytes to validate. File sources are
// not supported because KalkanCrypt's validation function accepts certificate
// bytes, not a certificate path. DER is passed through as DER; PEM and
// base64 sources are decoded to DER before the native call. Raw/auto sources
// are passed through unchanged for KalkanCrypt's native autodetection.
Certificate Source
// Mode selects no external validation, CRL validation, or OCSP validation.
// The zero value is rejected; choose CertificateValidationNone explicitly
// only when revocation checking is intentionally disabled.
Mode CertificateValidationMode
// RevocationSource is the CRL path or OCSP URL. For OCSP, an empty value uses
// the client's environment default or WithOCSPURL override.
RevocationSource string
// CheckTime is the validation time. Zero lets KalkanCrypt use its own
// default behavior.
CheckTime time.Time
// ReturnOCSPResponse requests the raw OCSP response from KalkanCrypt.
ReturnOCSPResponse bool
// CertificateTimeCheck controls KalkanCrypt certificate-time validation.
CertificateTimeCheck CertificateTimeCheck
}
ValidateCertificateRequest describes certificate validation input.
type Verification ¶
type Verification struct {
// Valid is true when KalkanCrypt returned success.
Valid bool
// Info is KalkanCrypt's native verification information string.
Info string
// Data contains attached CMS payload data when KalkanCrypt returns it.
Data []byte
// SignerCert contains the selected signer certificate when KalkanCrypt
// returns it.
SignerCert []byte
}
Verification is returned by CMS and XML verification operations.
type VerifyCMSRequest ¶
type VerifyCMSRequest struct {
// Alias is forwarded to KalkanCrypt's VerifyData alias parameter.
Alias string
// Signature is the CMS/signature input. Use File for large signatures or
// Bytes for in-memory raw CMS bytes.
Signature Source
// Data is the detached payload. It is valid only when Detached is true. For
// detached verification the zero-value Source is rejected; Bytes(nil) or
// Bytes([]byte{}) means an explicit empty detached payload.
Data Source
// Detached verifies a detached CMS signature.
Detached bool
// Encoding describes the signature encoding when Signature does not specify
// one explicitly. It is most important for File sources because Go does not
// inspect file contents.
Encoding Encoding
// SignerID selects a signer certificate from multi-signer data.
SignerID int
// CertificateTimeCheck controls KalkanCrypt certificate-time validation.
CertificateTimeCheck CertificateTimeCheck
}
VerifyCMSRequest describes CMS verification input.
type VerifyXMLRequest ¶
type VerifyXMLRequest struct {
// Alias is forwarded to KalkanCrypt's VerifyXML alias parameter.
Alias string
// XML is the signed XML document to verify.
XML Source
// ExpectedBodyID, when set, requires the verified XML signature to reference
// the single SOAP Body with this wsu:Id. Empty value preserves legacy VerifyXML
// behavior and does not bind verification to a SOAP Body.
ExpectedBodyID string
// Canonicalization selects the XML canonicalization algorithm.
Canonicalization XMLCanonicalization
// CertificateTimeCheck controls certificate-time validation.
CertificateTimeCheck CertificateTimeCheck
}
VerifyXMLRequest describes XML verification input.
type VerifyZIPRequest ¶
type VerifyZIPRequest struct {
// Path is the ZIP container path passed to KalkanCrypt.
Path string
// SignerID selects a signer certificate from multi-signer containers when
// ReturnSignerCertificate is true.
SignerID int
// ReturnSignerCertificate asks VerifyZIP to also extract the selected signer
// certificate after successful ZIP verification.
ReturnSignerCertificate bool
// CertificateTimeCheck controls KalkanCrypt certificate-time validation.
CertificateTimeCheck CertificateTimeCheck
}
VerifyZIPRequest describes ZIP signature verification.
type XMLCanonicalization ¶
type XMLCanonicalization int
XMLCanonicalization selects the XML canonicalization algorithm passed to KalkanCrypt. The zero value selects XMLCanonicalizationInclusive.
const ( // XMLCanonicalizationInclusive selects inclusive XML canonicalization. XMLCanonicalizationInclusive XMLCanonicalization = iota // XMLCanonicalizationInclusiveWithComments selects inclusive XML // canonicalization and preserves comments. XMLCanonicalizationInclusiveWithComments // XMLCanonicalizationInclusive11 selects inclusive XML canonicalization 1.1. XMLCanonicalizationInclusive11 // XMLCanonicalizationInclusive11WithComments selects inclusive XML // canonicalization 1.1 and preserves comments. XMLCanonicalizationInclusive11WithComments // XMLCanonicalizationExclusive selects exclusive XML canonicalization. XMLCanonicalizationExclusive // XMLCanonicalizationExclusiveWithComments selects exclusive XML // canonicalization and preserves comments. XMLCanonicalizationExclusiveWithComments )
type ZIPSignerCertificateRequest ¶
type ZIPSignerCertificateRequest struct {
// Path is the ZIP container path passed to KalkanCrypt.
Path string
// SignerID selects a signer certificate from multi-signer containers.
SignerID int
// CertificateTimeCheck controls KalkanCrypt certificate-time validation.
CertificateTimeCheck CertificateTimeCheck
}
ZIPSignerCertificateRequest describes signer-certificate extraction from a ZIP container.
type ZIPVerification ¶
type ZIPVerification struct {
// Valid is true when KalkanCrypt returned success.
Valid bool
// Info is KalkanCrypt's native ZIP verification information string.
Info string
// SignerCert contains the selected signer certificate when requested.
SignerCert []byte
}
ZIPVerification is returned by VerifyZIP.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package ckalkan provides a low-level Go binding for libkalkancryptwr.
|
Package ckalkan provides a low-level Go binding for libkalkancryptwr. |
|
internal/kalkancrypt
Package kalkancrypt contains the private KalkanCrypt ABI boundary.
|
Package kalkancrypt contains the private KalkanCrypt ABI boundary. |