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. Source retains caller-provided byte slices; do not mutate them until the operation returns. File source paths are passed unchanged after validation.
VerifyXML requires ExpectedBodyID for SOAP envelopes. Accepted non-SOAP input is passed to KalkanCrypt unchanged.
Native calls are process-global and serialized. Context cancellation stops lock waits but cannot interrupt an active KalkanCrypt call; hard deadlines require process isolation.
Open requires WithLibraryPath with an absolute path to the native KalkanCrypt library. 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 CertificateRole
- type CertificateSubjectType
- type CertificateTimeCheck
- type CertificateType
- type CertificateValidation
- type CertificateValidationMode
- type Client
- func (c *Client) Close() error
- func (c *Client) CloseContext(ctx context.Context) error
- func (c *Client) ExtractZIPSignerCertificate(ctx context.Context, req ExtractZIPSignerCertificateRequest) ([]byte, 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) (*Verification, 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)
- type Digest
- type Encoding
- type ExtractZIPSignerCertificateRequest
- type HashAlgorithm
- type HashRequest
- type KeyStore
- type KeyStoreType
- type 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
Examples ¶
Constants ¶
const CertificateInfoAllFields = CertificateInfoSubject | CertificateInfoSerialNumber | CertificateInfoValidFrom | CertificateInfoValidUntil | CertificateInfoIssuer | CertificateInfoPolicy | CertificateInfoKeyUsage | CertificateInfoExtKeyUsage | CertificateInfoAuthKeyID | CertificateInfoSubjKeyID | CertificateInfoAlgorithmSignCert | CertificateInfoPublicKey | CertificateInfoOCSPURL | CertificateInfoCRLURL | CertificateInfoDeltaCRLURL | CertificateInfoSubjectCountry | CertificateInfoSubjectSerialNumber | CertificateInfoSubjectOrganization | CertificateInfoSubjectOrganizationalUnit
CertificateInfoAllFields requests the same properties as X509CertificateGetInfo.
const ( // DefaultMaxOutputBufferSize is the default hard limit for each native // output buffer. It is a security and availability boundary, not a promise // that any operation should consume the full amount. Applications may set a // smaller limit with WithMaxOutputBufferSize. DefaultMaxOutputBufferSize = ckalkan.DefaultMaxOutputBufferSize )
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
// SubjectCountry is the native subject country value.
SubjectCountry string
// SubjectSerialNumber is the native subject serialNumber value.
SubjectSerialNumber string
// SubjectOrganization is the native subject organization value.
SubjectOrganization string
// SubjectOrganizationalUnit is the native subject organizational unit value.
SubjectOrganizationalUnit 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
// IIN is parsed from Kazakhstan subject serialNumber values prefixed with "IIN".
IIN string
// BIN is parsed from Kazakhstan subject OU values prefixed with "BIN".
BIN string
// SubjectType is inferred from known Kazakhstan NCA policy OIDs or IIN/BIN.
SubjectType CertificateSubjectType
// Roles contains recognized Kazakhstan NCA role policy OIDs.
Roles []CertificateRole
}
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 // CertificateInfoSubjectCountry requests the subject country value. CertificateInfoSubjectCountry // CertificateInfoSubjectSerialNumber requests the subject serialNumber value. CertificateInfoSubjectSerialNumber // CertificateInfoSubjectOrganization requests the subject organization value. CertificateInfoSubjectOrganization // CertificateInfoSubjectOrganizationalUnit requests the subject organizational unit value. CertificateInfoSubjectOrganizationalUnit )
type CertificateRole ¶ added in v0.5.0
type CertificateRole string
CertificateRole identifies known Kazakhstan NCA role policy OIDs.
const ( // CertificateRolePersonSystem identifies policy OID 1.2.398.3.3.4.1.1.1. CertificateRolePersonSystem CertificateRole = kzPolicyPersonSystem // CertificateRoleFirstHead identifies policy OID 1.2.398.3.3.4.1.2.1. CertificateRoleFirstHead CertificateRole = kzPolicyFirstHead // CertificateRoleSigner identifies policy OID 1.2.398.3.3.4.1.2.2. CertificateRoleSigner CertificateRole = kzPolicySigner // CertificateRoleFinancialSigner identifies policy OID 1.2.398.3.3.4.1.2.3. CertificateRoleFinancialSigner CertificateRole = kzPolicyFinancialSigner // CertificateRoleHR identifies policy OID 1.2.398.3.3.4.1.2.4. CertificateRoleHR CertificateRole = kzPolicyHR // CertificateRoleEmployee identifies policy OID 1.2.398.3.3.4.1.2.5. CertificateRoleEmployee CertificateRole = kzPolicyEmployee // CertificateRoleLegalEntitySystem identifies policy OID 1.2.398.3.3.4.1.2.6. CertificateRoleLegalEntitySystem CertificateRole = kzPolicyLegalEntitySystem )
type CertificateSubjectType ¶ added in v0.5.0
type CertificateSubjectType string
CertificateSubjectType identifies known Kazakhstan NCA subject type policy OIDs.
const ( // CertificateSubjectUnknown means the subject type could not be inferred. CertificateSubjectUnknown CertificateSubjectType = "" // CertificateSubjectPerson identifies policy OID 1.2.398.3.3.4.1.1. CertificateSubjectPerson CertificateSubjectType = kzPolicyPerson // CertificateSubjectLegalEntity identifies policy OID 1.2.398.3.3.4.1.2. CertificateSubjectLegalEntity CertificateSubjectType = kzPolicyLegalEntity )
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 {
// 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 rejected by ValidateCertificate. 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"
)
const (
testTSAURL = "http://test.pki.gov.kz/tsp/"
testOCSPURL = "http://test.pki.gov.kz/ocsp/"
)
func main() {
ctx := context.Background()
client, err := kalkan.Open(ctx,
kalkan.WithLibraryPath("/usr/local/lib/libkalkancryptwr-64.so"),
kalkan.WithTSAURL(testTSAURL),
kalkan.WithOCSPURL(testOCSPURL),
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. Close waits for any in-flight native call to return before closing the native library.
func (*Client) CloseContext ¶ added in v0.5.0
CloseContext releases the native KalkanCrypt session with context-aware waiting. It may be called more than once.
The context can stop waiting for a close that is queued behind another native call or already running in another goroutine. It cannot interrupt a KalkanCrypt call after control has entered the shared library. Once CloseContext starts closing a client, new operations are rejected even if the caller stops waiting.
func (*Client) ExtractZIPSignerCertificate ¶ added in v0.5.0
func (c *Client) ExtractZIPSignerCertificate(ctx context.Context, req ExtractZIPSignerCertificateRequest) ([]byte, error)
ExtractZIPSignerCertificate extracts a signer certificate without verifying the ZIP signature.
Example ¶
package main
import (
"context"
"log"
"os"
"github.com/skarm/kalkan"
)
const (
testTSAURL = "http://test.pki.gov.kz/tsp/"
testOCSPURL = "http://test.pki.gov.kz/ocsp/"
)
func main() {
ctx := context.Background()
client := openExampleClient(ctx)
certificate, err := client.ExtractZIPSignerCertificate(ctx, kalkan.ExtractZIPSignerCertificateRequest{
Path: "/data/document.signed.zip",
})
if err != nil {
_ = client.Close()
log.Fatal(err)
}
defer client.Close()
_ = certificate
}
func openExampleClient(ctx context.Context) *kalkan.Client {
client, err := kalkan.Open(ctx,
kalkan.WithLibraryPath("/usr/local/lib/libkalkancryptwr-64.so"),
kalkan.WithTSAURL(testTSAURL),
kalkan.WithOCSPURL(testOCSPURL),
)
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) 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"
)
const (
testTSAURL = "http://test.pki.gov.kz/tsp/"
testOCSPURL = "http://test.pki.gov.kz/ocsp/"
)
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.WithLibraryPath("/usr/local/lib/libkalkancryptwr-64.so"),
kalkan.WithTSAURL(testTSAURL),
kalkan.WithOCSPURL(testOCSPURL),
)
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"
)
const (
testTSAURL = "http://test.pki.gov.kz/tsp/"
testOCSPURL = "http://test.pki.gov.kz/ocsp/"
)
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.WithLibraryPath("/usr/local/lib/libkalkancryptwr-64.so"),
kalkan.WithTSAURL(testTSAURL),
kalkan.WithOCSPURL(testOCSPURL),
)
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"
)
const (
testTSAURL = "http://test.pki.gov.kz/tsp/"
testOCSPURL = "http://test.pki.gov.kz/ocsp/"
)
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.WithLibraryPath("/usr/local/lib/libkalkancryptwr-64.so"),
kalkan.WithTSAURL(testTSAURL),
kalkan.WithOCSPURL(testOCSPURL),
)
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"
)
const (
testTSAURL = "http://test.pki.gov.kz/tsp/"
testOCSPURL = "http://test.pki.gov.kz/ocsp/"
)
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.WithLibraryPath("/usr/local/lib/libkalkancryptwr-64.so"),
kalkan.WithTSAURL(testTSAURL),
kalkan.WithOCSPURL(testOCSPURL),
)
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"
)
const (
testTSAURL = "http://test.pki.gov.kz/tsp/"
testOCSPURL = "http://test.pki.gov.kz/ocsp/"
)
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.WithLibraryPath("/usr/local/lib/libkalkancryptwr-64.so"),
kalkan.WithTSAURL(testTSAURL),
kalkan.WithOCSPURL(testOCSPURL),
)
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"
)
const (
testTSAURL = "http://test.pki.gov.kz/tsp/"
testOCSPURL = "http://test.pki.gov.kz/ocsp/"
)
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.WithLibraryPath("/usr/local/lib/libkalkancryptwr-64.so"),
kalkan.WithTSAURL(testTSAURL),
kalkan.WithOCSPURL(testOCSPURL),
)
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"
)
const (
testTSAURL = "http://test.pki.gov.kz/tsp/"
testOCSPURL = "http://test.pki.gov.kz/ocsp/"
)
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.OCSPResponse
}
func openExampleClient(ctx context.Context) *kalkan.Client {
client, err := kalkan.Open(ctx,
kalkan.WithLibraryPath("/usr/local/lib/libkalkancryptwr-64.so"),
kalkan.WithTSAURL(testTSAURL),
kalkan.WithOCSPURL(testOCSPURL),
)
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"
)
const (
testTSAURL = "http://test.pki.gov.kz/tsp/"
testOCSPURL = "http://test.pki.gov.kz/ocsp/"
)
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.SignerCert
}
func openExampleClient(ctx context.Context) *kalkan.Client {
client, err := kalkan.Open(ctx,
kalkan.WithLibraryPath("/usr/local/lib/libkalkancryptwr-64.so"),
kalkan.WithTSAURL(testTSAURL),
kalkan.WithOCSPURL(testOCSPURL),
)
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) (*Verification, error)
VerifyZIP verifies a KalkanCrypt ZIP container.
Example ¶
package main
import (
"context"
"log"
"os"
"github.com/skarm/kalkan"
)
const (
testTSAURL = "http://test.pki.gov.kz/tsp/"
testOCSPURL = "http://test.pki.gov.kz/ocsp/"
)
func main() {
ctx := context.Background()
client := openExampleClient(ctx)
verification, err := client.VerifyZIP(ctx, kalkan.VerifyZIPRequest{
Path: "/data/document.signed.zip",
})
if err != nil {
_ = client.Close()
log.Fatal(err)
}
defer client.Close()
_ = verification.Info
}
func openExampleClient(ctx context.Context) *kalkan.Client {
client, err := kalkan.Open(ctx,
kalkan.WithLibraryPath("/usr/local/lib/libkalkancryptwr-64.so"),
kalkan.WithTSAURL(testTSAURL),
kalkan.WithOCSPURL(testOCSPURL),
)
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.
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 ExtractZIPSignerCertificateRequest ¶ added in v0.5.0
type ExtractZIPSignerCertificateRequest struct {
// Path is passed unchanged to KalkanCrypt. Keep the referenced file unchanged
// until ExtractZIPSignerCertificate returns.
Path string
// SignerID selects a signer certificate from multi-signer containers.
SignerID int
// CertificateTimeCheck controls KalkanCrypt certificate-time validation.
CertificateTimeCheck CertificateTimeCheck
}
ExtractZIPSignerCertificateRequest describes signer-certificate extraction from a ZIP container.
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 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 make memory inputs unlimited.
func WithMaxOutputBufferSize ¶
WithMaxOutputBufferSize sets the hard cap for the low-level KalkanCrypt output-buffer retry policy. Zero restores DefaultMaxOutputBufferSize. A positive value selects a smaller or larger cap, subject to the native C int ABI maximum. A negative value makes Open return ErrInvalidInput.
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 passed unchanged to KalkanCrypt. Keep the referenced file
// unchanged until SignZIP returns.
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.
// The path must not exist. KalkanCrypt creates it without an atomic
// create-if-absent guarantee.
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 is the certificate to validate. File sources are unsupported;
// PEM and base64 are decoded to DER, while raw, auto, and DER are passed
// unchanged.
Certificate Source
// Mode selects the revocation check. The zero value is invalid.
Mode CertificateValidationMode
// RevocationSource is a CRL path or OCSP URL. An empty OCSP source uses the
// configured OCSP URL.
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 {
// Info is KalkanCrypt's native verification information string.
Info string
// Data contains attached CMS payload data when KalkanCrypt returns it. XML
// and ZIP verification leave it empty.
Data []byte
// SignerCert contains the selected signer certificate when KalkanCrypt
// returns it. XML and ZIP verification leave it empty.
SignerCert []byte
}
Verification is returned by CMS, XML, and ZIP 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 and
// must be an in-memory source: KalkanCrypt's KC_IN_FILE flag applies to the
// CMS signature input during verification. 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 binds verification to a SOAP Body wsu:Id. It is required for
// SOAP 1.1 and SOAP 1.2 and must be empty for non-SOAP XML.
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 passed unchanged to KalkanCrypt. Keep the referenced file unchanged
// until VerifyZIP returns.
Path string
// 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 )
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. |