certificate

package
v0.1.59999 Latest Latest
Warning

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

Go to latest
Published: Jun 8, 2026 License: MIT Imports: 5 Imported by: 4

README

certificate

-- import "github.com/go-i2p/common/certificate"

certificate.svg

Package certificate implements the certificate common-structure of I2P.

Usage

const (
	CERT_NULL     = iota //nolint:golint
	CERT_HASHCASH        //nolint:golint
	CERT_HIDDEN          //nolint:golint
	CERT_SIGNED          //nolint:golint
	CERT_MULTIPLE        //nolint:golint
	CERT_KEY             //nolint:golint
)

Certificate Types

const CERT_DEFAULT_TYPE_SIZE = 1

CERT_DEFAULT_TYPE_SIZE is the size in bytes for the certificate type field

const CERT_EMPTY_PAYLOAD_SIZE = 0

CERT_EMPTY_PAYLOAD_SIZE represents the size of an empty payload

const CERT_KEY_SIG_TYPE_OFFSET = 0

CERT_KEY_SIG_TYPE_OFFSET is the byte offset where signature type begins in KEY certificate payload

const CERT_LENGTH_FIELD_END = 3

CERT_LENGTH_FIELD_END is the end index for the certificate length field (2 bytes total)

const CERT_LENGTH_FIELD_SIZE = 2

CERT_LENGTH_FIELD_SIZE is the size in bytes for the certificate length field

const CERT_LENGTH_FIELD_START = 1

CERT_LENGTH_FIELD_START is the start index for the certificate length field

const CERT_MAX_PAYLOAD_SIZE = 65535

CERT_MAX_PAYLOAD_SIZE is the maximum allowed size for certificate payload according to I2P specification (2 bytes can represent up to 65535)

const CERT_MAX_TYPE_VALUE = 255

CERT_MAX_TYPE_VALUE is the maximum valid certificate type value that fits in a single byte (0-255 range)

const CERT_MIN_KEY_PAYLOAD_SIZE = 4

CERT_MIN_KEY_PAYLOAD_SIZE is the minimum payload size required for KEY certificates to contain the signature type field (2 bytes minimum)

const CERT_MIN_SIZE = 3

CERT_MIN_SIZE is the minimum size of a valid Certificate in []byte 1 byte for type 2 bytes for payload length

const CERT_SIGNING_KEY_TYPE_SIZE = 2 //nolint:golint

CERT_SIGNING_KEY_TYPE_SIZE is the size in bytes of the signing key type field in key certificates

const CERT_TYPE_FIELD_END = 1

CERT_TYPE_FIELD_END is the end index for the certificate type field (1 byte)

func GetSignatureTypeFromCertificate
func GetSignatureTypeFromCertificate(cert Certificate) (int, error)

GetSignatureTypeFromCertificate extracts the signature type from a KEY certificate. Returns an error if the certificate is not a KEY type or if the payload is too short.

type Certificate
type Certificate struct {
}

Certificate is the representation of an I2P Certificate.

https://geti2p.net/spec/common-structures#certificate

func NewCertificate
func NewCertificate() *Certificate

NewCertificate creates a new Certificate with default NULL type

func NewCertificateDeux
func NewCertificateDeux(certType int, payload []byte) (*Certificate, error)

NewCertificateDeux creates a new Certificate with specified type and payload. Deprecated: Use NewCertificateWithType instead. This function will be removed in v2.0.

func NewCertificateWithType
func NewCertificateWithType(certType uint8, payload []byte) (*Certificate, error)

NewCertificateWithType creates a new Certificate with specified type and payload

func ReadCertificate
func ReadCertificate(data []byte) (certificate Certificate, remainder []byte, err error)

ReadCertificate creates a Certificate from []byte and returns any ExcessBytes at the end of the input. returns err if the certificate could not be read.

func (*Certificate) Bytes
func (c *Certificate) Bytes() []byte

Bytes returns the entire certificate in []byte form, trims payload to specified length.

func (*Certificate) Data
func (c *Certificate) Data() (data []byte)

Data returns the payload of a Certificate, payload is trimmed to the specified length.

func (*Certificate) ExcessBytes
func (c *Certificate) ExcessBytes() []byte

ExcessBytes returns the excess bytes in a certificate found after the specified payload length.

func (*Certificate) Length
func (c *Certificate) Length() (length int)

Length returns the payload length of a Certificate.

func (*Certificate) RawBytes
func (c *Certificate) RawBytes() []byte

RawBytes returns the entire certificate in []byte form, includes excess payload data.

func (*Certificate) Type
func (c *Certificate) Type() (certType int)

Type returns the Certificate type specified in the first byte of the Certificate,

certificate

github.com/go-i2p/common/certificate

go-i2p template file

Documentation

Overview

Package certificate implements the certificate common-structure of I2P.

Package certificate implements the certificate common-structure of I2P.

Package certificate implements the certificate common-structure of I2P.

Package certificate implements the certificate common-structure of I2P.

Package certificate implements the I2P Certificate common data structure according to specification version 0.9.67.

Certificates are used throughout I2P to provide cryptographic metadata about keys, signatures, and other security parameters. They support multiple certificate types and provide flexible payload storage.

Overview

The Certificate structure consists of:

  • Type: Certificate type identifier (NULL, HASHCASH, HIDDEN, SIGNED, MULTIPLE, KEY)
  • Length: Payload length in bytes (0-65535)
  • Payload: Variable-length data specific to the certificate type

Certificate Types

The package supports six certificate types:

  • CERT_NULL (0): No certificate (legacy)
  • CERT_HASHCASH (1): HashCash proof-of-work
  • CERT_HIDDEN (2): Hidden router certificate (routers may not announce hidden status)
  • CERT_SIGNED (3): Signed certificate
  • CERT_MULTIPLE (4): Multiple certificates
  • CERT_KEY (5): Key certificate with signing/crypto type info

Safe Constructors

The package provides validated construction through the builder pattern:

// Create a KEY certificate with validation
builder := certificate.NewCertificateBuilder()
builder, err := builder.WithKeyTypes(7, 4)  // Ed25519/X25519
if err != nil {
    return err
}
cert, err := builder.Build()
if err != nil {
    return err
}

// Create a NULL certificate (the default type; no further configuration needed)
cert, err := certificate.NewCertificateBuilder().Build()

Parsing from Bytes

Certificates can be safely parsed from byte streams:

cert, remainder, err := certificate.ReadCertificate(data)
if err != nil {
    return err
}
if !cert.IsValid() {
    return errors.New("invalid certificate")
}

Validation

All certificates support validation to ensure proper initialization:

// Boolean validation check
if !cert.IsValid() {
    return errors.New("invalid certificate")
}

// Builder-level validation (before Build)
if err := builder.Validate(); err != nil {
    // Fix configuration before building
}

Accessing Certificate Data

Certificate fields can be safely accessed with error handling:

certType, err := cert.Type()
if err != nil {
    return err
}

length, err := cert.Length()
if err != nil {
    return err
}

payload, err := cert.Data()
if err != nil {
    return err
}

Builder Pattern

The CertificateBuilder provides fluent API with early validation:

// Builder validates configuration at each step
builder := NewCertificateBuilder()
builder, err := builder.WithType(CERT_KEY)
if err != nil {
    return err  // Invalid type rejected immediately
}

// Validate before building
if err := builder.Validate(); err != nil {
    // Fix configuration issues
}

cert, err := builder.Build()

Best Practices

  • Use the builder pattern for creating new certificates
  • Always validate certificates after parsing from bytes
  • Use safe accessor methods (Type(), Length(), Data()) with error checking
  • Prefer KEY certificates for modern cryptographic parameters

Specification

Reference: https://geti2p.net/spec/common-structures#certificate

This implementation follows I2P specification version 0.9.67 and provides comprehensive validation and error handling for all certificate operations.

Index

Constants

View Source
const (
	CERT_NULL     = iota //nolint:golint
	CERT_HASHCASH        //nolint:golint
	CERT_HIDDEN          //nolint:golint
	CERT_SIGNED          //nolint:golint
	CERT_MULTIPLE        //nolint:golint
	CERT_KEY             //nolint:golint
)

Certificate Types

View Source
const CERT_CPK_SLOT_SIZE = 256

CERT_CPK_SLOT_SIZE is the number of bytes in the keys_and_cert structure reserved for the crypto public key. Crypto keys larger than this store the overflow bytes as excess crypto public key data in the KEY certificate payload after any excess signing key bytes.

View Source
const CERT_CRYPTO_KEY_TYPE_SIZE = 2

CERT_CRYPTO_KEY_TYPE_SIZE is the size in bytes of the crypto key type field in key certificates

View Source
const CERT_DEFAULT_TYPE_SIZE = 1

CERT_DEFAULT_TYPE_SIZE is the size in bytes for the certificate type field

View Source
const CERT_EMPTY_PAYLOAD_SIZE = 0

CERT_EMPTY_PAYLOAD_SIZE represents the size of an empty payload

View Source
const CERT_KEY_CRYPTO_TYPE_OFFSET = 2

CERT_KEY_CRYPTO_TYPE_OFFSET is the byte offset where crypto key type begins in KEY certificate payload

View Source
const CERT_KEY_SIG_TYPE_OFFSET = 0

CERT_KEY_SIG_TYPE_OFFSET is the byte offset where signature type begins in KEY certificate payload

View Source
const CERT_LENGTH_FIELD_END = 3

CERT_LENGTH_FIELD_END is the end index for the certificate length field (2 bytes total)

View Source
const CERT_LENGTH_FIELD_SIZE = 2

CERT_LENGTH_FIELD_SIZE is the size in bytes for the certificate length field

View Source
const CERT_LENGTH_FIELD_START = 1

CERT_LENGTH_FIELD_START is the start index for the certificate length field

View Source
const CERT_MAX_PAYLOAD_SIZE = 65535

CERT_MAX_PAYLOAD_SIZE is the maximum allowed size for certificate payload according to I2P specification (2 bytes can represent up to 65535)

View Source
const CERT_MAX_TYPE_VALUE = 255

CERT_MAX_TYPE_VALUE is the maximum valid certificate type value that fits in a single byte (0-255 range)

View Source
const CERT_MIN_KEY_PAYLOAD_SIZE = 4

CERT_MIN_KEY_PAYLOAD_SIZE is the minimum payload size required for KEY certificates to contain the signature type field (2 bytes minimum)

View Source
const CERT_MIN_SIZE = 3

CERT_MIN_SIZE is the minimum size of a valid Certificate in []byte 1 byte for type 2 bytes for payload length

View Source
const CERT_SIGNED_PAYLOAD_LONG = 72

CERT_SIGNED_PAYLOAD_LONG is the spec-defined SIGNED certificate payload length containing a 40-byte DSA signature followed by a 32-byte Hash of the signing Destination.

View Source
const CERT_SIGNED_PAYLOAD_SHORT = 40

CERT_SIGNED_PAYLOAD_SHORT is the spec-defined SIGNED certificate payload length containing a 40-byte DSA signature only.

View Source
const CERT_SIGNING_KEY_TYPE_SIZE = 2 //nolint:golint

CERT_SIGNING_KEY_TYPE_SIZE is the size in bytes of the signing key type field in key certificates

View Source
const CERT_SPK_SLOT_SIZE = 128

CERT_SPK_SLOT_SIZE is the number of bytes in the keys_and_cert structure reserved for the signing public key. Signing keys larger than this store the overflow bytes as excess signing public key data in the KEY certificate payload after the 4-byte type header.

View Source
const CERT_TYPE_FIELD_END = 1

CERT_TYPE_FIELD_END is the end index for the certificate type field (1 byte)

Variables

This section is empty.

Functions

func BuildKeyTypePayload added in v0.0.6

func BuildKeyTypePayload(signingType, cryptoType int) ([]byte, error)

BuildKeyTypePayload is a convenience function to build key type payload without using builder. This is useful when you just need to generate the payload bytes.

Parameters:

  • signingType: The signing key type (must be non-negative and <= 65535)
  • cryptoType: The crypto key type (must be non-negative and <= 65535)

Returns:

  • []byte: The 4-byte payload [signing_type][crypto_type]
  • error: Non-nil if either type is negative or exceeds uint16 range

func GetCryptoTypeFromCertificate added in v0.1.5

func GetCryptoTypeFromCertificate(cert Certificate) (int, error)

GetCryptoTypeFromCertificate extracts the crypto public key type from a KEY certificate. Returns -1 (not 0) on every error path to avoid ambiguity with the valid ElGamal crypto type code 0. Callers must always check the returned error before using the int.

func GetExcessCryptoPublicKeyData added in v0.1.5

func GetExcessCryptoPublicKeyData(cert Certificate, cryptoKeySize, excessSigningLen int) ([]byte, error)

GetExcessCryptoPublicKeyData extracts the excess crypto public key bytes from a KEY certificate. For crypto key types whose total length exceeds CERT_CPK_SLOT_SIZE (256) bytes, the overflow is stored after any excess signing key data in the payload. The excessSigningLen parameter is the number of excess signing key bytes already stored before the crypto excess (= max(0, signingKeySize - CERT_SPK_SLOT_SIZE)). Returns nil (no error) when cryptoKeySize <= CERT_CPK_SLOT_SIZE.

func GetExcessSigningPublicKeyData added in v0.1.5

func GetExcessSigningPublicKeyData(cert Certificate, signingKeySize int) ([]byte, error)

GetExcessSigningPublicKeyData extracts the excess signing public key bytes from a KEY certificate. For signing key types whose total length exceeds CERT_SPK_SLOT_SIZE (128) bytes, the overflow is stored starting at byte CERT_MIN_KEY_PAYLOAD_SIZE of the payload. Returns nil (no error) when signingKeySize <= CERT_SPK_SLOT_SIZE.

func GetSignatureTypeFromCertificate

func GetSignatureTypeFromCertificate(cert Certificate) (int, error)

GetSignatureTypeFromCertificate extracts the signature type from a KEY certificate. Returns an error if the certificate is not a KEY type or if the payload is too short.

Types

type Certificate

type Certificate struct {
	// contains filtered or unexported fields
}

Certificate is the representation of an I2P Certificate.

https://geti2p.net/spec/common-structures#certificate

func NewCertificate

func NewCertificate() *Certificate

NewCertificate creates a new Certificate with default NULL type. The returned certificate serializes to exactly CERT_MIN_SIZE (3) bytes: 1 byte type (0x00 = NULL) + 2 byte length (0x0000) + 0 byte payload.

func NewCertificateWithType

func NewCertificateWithType(certType uint8, payload []byte) (*Certificate, error)

NewCertificateWithType creates a new Certificate with specified type and payload

func ReadCertificate

func ReadCertificate(data []byte) (certificate *Certificate, remainder []byte, err error)

ReadCertificate creates a Certificate from []byte and returns any remaining bytes after the certificate. Returns nil certificate on error (not partial certificate). Per the I2P spec, type-specific payload length constraints are enforced as hard errors.

func (*Certificate) Bytes

func (c *Certificate) Bytes() []byte

Bytes returns the entire certificate in []byte form, trims payload to specified length. Returns nil if the certificate is nil or not initialized.

func (*Certificate) Data

func (c *Certificate) Data() ([]byte, error)

Data returns a copy of the payload of a Certificate, trimmed to the declared length. The returned slice is a defensive copy — callers may mutate it without affecting the certificate's internal state. Returns error if length is invalid.

func (*Certificate) Equals added in v0.1.5

func (c *Certificate) Equals(other *Certificate) bool

Equals returns true if the two certificates are identical in type, length, and payload. Two nil or uninitialized certificates are considered equal. A nil certificate and a valid certificate are never equal.

func (*Certificate) GoString added in v0.1.5

func (c *Certificate) GoString() string

GoString returns a Go-syntax representation of the Certificate for debugging. Implements the fmt.GoStringer interface.

func (*Certificate) IsValid added in v0.1.0

func (c *Certificate) IsValid() bool

IsValid returns true if the certificate is fully initialized and valid. This method checks that all required fields (kind, len) are present and non-empty. Note: payload can be empty for NULL certificates.

func (*Certificate) Length

func (c *Certificate) Length() (length int, err error)

Length returns the payload length of a Certificate, with validation and error context.

func (*Certificate) RawBytes

func (c *Certificate) RawBytes() []byte

RawBytes returns the entire certificate in []byte form, includes excess payload data. Returns nil if the certificate is nil or not initialized.

func (*Certificate) String added in v0.1.5

func (c *Certificate) String() string

String returns a human-readable representation of the Certificate. Returns "Certificate{invalid}" for nil or uninitialized certificates.

func (*Certificate) Type

func (c *Certificate) Type() (certType int, err error)

Type returns the certificate type as int, with validation and error context. The type is specified in the first byte of the Certificate.

func (*Certificate) Validate added in v0.1.5

func (c *Certificate) Validate() error

Validate checks that the Certificate is properly initialized and has consistent internal structure. Returns an error describing the first issue found, or nil if valid.

type CertificateBuilder added in v0.0.6

type CertificateBuilder struct {
	// contains filtered or unexported fields
}

CertificateBuilder provides a fluent interface for building certificates. This pattern simplifies certificate construction, especially for complex cases with custom payloads or key types.

Example usage:

cert, err := certificate.NewCertificateBuilder().
    WithKeyTypes(7, 4). // Ed25519 signing, X25519 crypto
    Build()

func NewCertificateBuilder added in v0.0.6

func NewCertificateBuilder() *CertificateBuilder

NewCertificateBuilder creates a new certificate builder with default NULL type.

func (*CertificateBuilder) Build added in v0.0.6

func (cb *CertificateBuilder) Build() (*Certificate, error)

Build creates the certificate with the configured options. Returns error if the configuration is invalid.

Example:

cert, err := NewCertificateBuilder().
    WithKeyTypes(7, 4).
    Build()

func (*CertificateBuilder) Validate added in v0.1.0

func (cb *CertificateBuilder) Validate() error

Validate checks the builder configuration for consistency. This allows catching configuration errors before calling Build().

Example:

builder := NewCertificateBuilder().WithType(CERT_KEY)
if err := builder.Validate(); err != nil {
    // Fix configuration before building
}

func (*CertificateBuilder) WithKeyTypes added in v0.0.6

func (cb *CertificateBuilder) WithKeyTypes(signingType, cryptoType int) (*CertificateBuilder, error)

WithKeyTypes sets signing and crypto key types (for CERT_KEY type). This is a convenience method that automatically:

  • Sets the certificate type to CERT_KEY
  • Builds the appropriate 4-byte payload

Parameters:

  • signingType: The signing key type (e.g., 7 for Ed25519)
  • cryptoType: The crypto key type (e.g., 4 for X25519)

Returns error if the key types are invalid (negative values or exceed uint16 range). On error, the builder retains its previous state and remains usable. Callers must check the returned error; ignoring it will silently proceed with the previously-set key types.

Example:

builder.WithKeyTypes(7, 4) // Ed25519 signing, X25519 crypto

func (*CertificateBuilder) WithPayload added in v0.0.6

func (cb *CertificateBuilder) WithPayload(payload []byte) (*CertificateBuilder, error)

WithPayload sets custom payload data. This overrides any payload that would be generated from key types. Returns error if the payload exceeds the maximum allowed size. On error, the builder retains its previous state and remains usable. Callers must check the returned error; ignoring it will silently proceed with the previously-set payload.

Example:

builder, err = builder.WithPayload(signatureData)

func (*CertificateBuilder) WithType added in v0.0.6

func (cb *CertificateBuilder) WithType(certType uint8) (*CertificateBuilder, error)

WithType sets the certificate type. Valid types are: CERT_NULL, CERT_HASHCASH, CERT_HIDDEN, CERT_SIGNED, CERT_MULTIPLE, CERT_KEY. Returns error if the certificate type is invalid.

On error, the builder retains its previous state and remains usable. Callers must check the returned error; ignoring it will silently proceed with the previously-set certificate type.

Example:

builder.WithType(certificate.CERT_KEY)

Jump to

Keyboard shortcuts

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