DAT Go Library
GitHub / Test Code pkg.go.devরিপোজিটরি
bash
Requires: Go >= 1.25 (
crypto/ecdsaraw key parsing replaced the deprecatedelliptic.Marshalfamily)
উদাহরণ: DAT সার্টিফিকেট ম্যানেজমেন্ট সার্ভিস
init
go
// logger example
opts := &slog.HandlerOptions{
Level: slog.LevelDebug,
}
logger := slog.New(slog.NewTextHandler(os.Stdout, opts))
builder, err := dat.NewDatCmsManagerBuilder().
Url("http://localhost:8088")
if err != nil {
return err
}
manager, err := builder.
// IntervalOff(). // disable auto sync
Interval(60 * time.Second).
Logger(logger).
Token("12345678901b").
Build()
if err != nil {
return err
}
// Build() hands back the manager even when the first sync failed, so that a
// later tick can still recover. Ask for the failure instead of assuming success.
if syncErr := manager.LastError(); syncErr != nil {
logger.Warn("certificates are not being refreshed yet", "code", dat.Code(syncErr))
}
// manual sync — returns error
// _ = manager.Sync()issue / parse
go
plain := "Unicode 유니코드 ユニコード 万国码 يونيكود यूनिकोड Юникод 🦄💻"
secure := "Ciphertext 암호문 暗号文 密文 Шифротекст Texte chiffré Geheimtext نص مشفر सिफरपाठ 🔐"
datStr, err := manager.Issue(plain, secure)
if err != nil {
return err
}
fmt.Printf("dat: %v\n", datStr)
payload, err := manager.Parse(datStr)
if err != nil {
return err
}
if plain != payload.PlainText() {
return fmt.Errorf("plain text mismatch: expected %q, got %q", plain, payload.PlainText())
}
if secure != payload.SecureText() {
return fmt.Errorf("secure text mismatch: expected %q, got %q", secure, payload.SecureText())
}
fmt.Printf("payload plain: %q\n", payload.PlainText())
fmt.Printf("payload secure: %q\n", payload.SecureText())ত্রুটি হ্যান্ডলিং
go
// needs "errors" in the file imports
// 1. Expiry, forgery and a malformed token each need a different response.
// They used to share one sentinel, so callers could not tell them apart.
payload, err := manager.Parse(datStr)
switch {
case err == nil:
fmt.Printf("plain: %q\n", payload.PlainText())
// Normal end of life. Let the caller refresh and try again.
case errors.Is(err, dat.ErrTokenExpired):
fmt.Println("expired: ask the client to re-issue")
// DAT_SIG_MISMATCH / DAT_CRYPTO_TAG_MISMATCH — direct evidence of tampering.
case dat.SecurityEvent(err):
logger.Warn("drop the session", "code", dat.Code(err))
// Anything else is simply a bad request.
default:
fmt.Printf("rejected %s: %v\n", dat.Code(err), err)
}
// 2. Never retry a permanent failure. A wrong token answers 401 forever.
if err := manager.Sync(); err != nil {
switch dat.Retry(err) {
case dat.RetryTransient:
logger.Info("retrying on the next tick", "code", dat.Code(err))
case dat.RetryPermanent:
logger.Error("fix the token, url or deployment", "code", dat.Code(err))
case dat.RetryState:
// not a failure — a sync was already running
}
}
// 3. Sync failures are never returned to the caller of Build(). Poll the
// manager to notice a stalled rollout.
if err := manager.LastError(); err != nil {
logger.Error("certificates are not being refreshed", "code", dat.Code(err))
}উদাহরণ: ম্যানুয়াল ইমপ্লিমেন্টেশন
go
manager := dat.NewManager()
// (cid, issuanceStart, issuanceDuration, datTtl, signatureAlgorithm, cryptoAlgorithm)
now := dat.NowUnixTimestamp()
cert, err := dat.GenerateCertificate(1, now-10, 3600, 1800, dat.EcdsaP256, dat.IvAes256Gcm)
if err != nil {
t.Fatal(err)
}
_, err = manager.ImportCertificates([]*dat.Certificate{cert}, false)
if err != nil {
t.Fatal(err)
}
plain := "Unicode 유니코드 ユニコード 万国码 يونيكود यूनिकोड Юникод 🦄💻"
secure := "Ciphertext 암호문 暗号文 密文 Шифротекст Texte chiffré Geheimtext نص مشفر सिफरपाठ 🔐"
datStr, err := manager.Issue(plain, secure)
if err != nil {
t.Fatal(err)
}
payload, err := manager.Parse(datStr)
if err != nil {
t.Fatal(err)
}
if payload.PlainText() != plain {
t.Errorf("expected plain %s, got %s", plain, payload.PlainText())
}
if payload.SecureText() != secure {
t.Errorf("expected secure %s, got %s", secure, payload.SecureText())
}
println(datStr)
println(payload.PlainText())
println(payload.SecureText())export
go
// ExportCertificates and GenerateCryptoKey both return an error — a failing RNG
// must never be silently turned into an all-zero key.
certs, err := manager.ExportCertificates()
if err != nil {
return err
}
crypto, err := dat.GenerateCryptoKey(dat.IvAes256Gcm)
if err != nil {
return err
}