openspalib

package module
v0.0.0-...-a127847 Latest Latest
Warning

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

Go to latest
Published: Feb 27, 2022 License: MIT Imports: 26 Imported by: 0

Documentation

Index

Constants

View Source
const (
	CipherSuite_RSA_AES_128_CBC_WITH_RSA_SHA256 = CipherSuiteId(0x1)

	// CipherSuite_Mock - DO NOT USE IN PRODUCTION! No cipher operations will be performed (i.e. no encryption & signing)
	CipherSuite_Mock = CipherSuiteId(0x0)
)
View Source
const (
	Version     = 2                       // version of the protocol
	PDUMaxSize  = 1408                    // bytes (UDP payload i.e. OpenSPA header + body)
	BodyMaxSize = PDUMaxSize - HeaderSize // bytes
)
View Source
const HeaderSize = 8 // bytes
View Source
const (
	PublicIPv4ResolverDefaultEndpoint = "https://ipv4.openspa.org"
)
View Source
const (
	RequestPacketBodySize = 68 // bytes, packet body size without the signature and TLV values
)
View Source
const (
	ResponsePacketBodySize = 24 // bytes
)

Variables

View Source
var (
	ErrDeviceIdInvalid         = errors.New("deviceId is invalid")
	ErrTimestampInvalid        = errors.New("timestamp is invalid")
	ErrUnsupportedStartPort    = errors.New("unsupported start port")
	ErrUnsupportedEndPort      = errors.New("unsupported end port")
	ErrStartEndPortMismatch    = errors.New("start port end port mismatch")
	ErrClientIpIsEmpty         = errors.New("client public ip is empty")
	ErrServerIpIsEmpty         = errors.New("server public ip is empty")
	ErrSignatureOffsetTooLarge = errors.New("signature offset too large")
)
View Source
var (
	ErrBadIP = errors.New("bad ip address")
)
View Source
var ErrHeaderTooShort = errors.New("header too short")
View Source
var (
	ErrMissingIPFieldResp = errors.New("missing ip field in response")
)

Functions

func CipherSuiteIsSupported

func CipherSuiteIsSupported(c CipherSuiteId) bool

CipherSuiteIsSupported returns true if the input CipherSuiteId is supported.

func NewRequest

func NewRequest(data RequestData, c CipherSuite) ([]byte, error)

NewRequest creates a Request struct, signs it and then encrypting its. The returned byte slice is the raw byte representation of the final request and should be sent over the wire to the OpenSPA server to be processed.

func TestingRsaKeyPair1

func TestingRsaKeyPair1() (*rsa.PrivateKey, *rsa.PublicKey)

TestingRsaKeyPair1 should NOT BE USED IN PRODUCTION. This is should be only used for testing purposes. You should generate your own private key using OpenSSL or similar RSA implementation.

func TestingRsaKeyPair2

func TestingRsaKeyPair2() (*rsa.PrivateKey, *rsa.PublicKey)

TestingRsaKeyPair2 should NOT BE USED IN PRODUCTION. This is should be only used for testing purposes. You should generate your own private key using OpenSSL or similar RSA implementation.

Types

type CipherSuiteId

type CipherSuiteId uint8

func CipherSuiteSupport

func CipherSuiteSupport() []CipherSuiteId

CipherSuiteSupport returns a slice of all CipherSuiteId that are supported. If the OS env variable `OSPA_CIPHER_SUITE_MOCK` is defined and set to "true" (case-insensitive), CipherSuite_Mock will be added to the slice of supported cipher suites.

func (CipherSuiteId) Bin

func (c CipherSuiteId) Bin() byte

type CryptoDecryptionMethod

type CryptoDecryptionMethod interface {
	Decrypt(ciphertext []byte) (plaintext []byte, err error)
}

type CryptoEncryptionMethod

type CryptoEncryptionMethod interface {
	Encrypt(plaintext []byte) (ciphertext []byte, err error)
}

type CryptoMethodMock

type CryptoMethodMock struct{}

CryptoMethodMock DO NOT USE THIS IN PRODUCTION!!! This mocks all cryptographic operations and does not encrypt/sign anything. This is only to be used for development testing.

func (CryptoMethodMock) CipherSuiteId

func (_ CryptoMethodMock) CipherSuiteId() CipherSuiteId

func (CryptoMethodMock) Decrypt

func (_ CryptoMethodMock) Decrypt(ciphertext []byte) (plaintext []byte, err error)

func (CryptoMethodMock) Encrypt

func (_ CryptoMethodMock) Encrypt(plaintext []byte) (ciphertext []byte, err error)

func (CryptoMethodMock) Sign

func (_ CryptoMethodMock) Sign(text []byte) (signature []byte, err error)

func (CryptoMethodMock) Verify

func (_ CryptoMethodMock) Verify(text, signature []byte) (valid bool, err error)

type CryptoSignatureMethod

type CryptoSignatureMethod interface {
	Sign(data []byte) (signature []byte, err error)
}

type CryptoSignatureVerificationMethod

type CryptoSignatureVerificationMethod interface {
	Verify(text, signature []byte) (valid bool, err error)
}

type ErrCipherSuiteNotSupported

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

func (ErrCipherSuiteNotSupported) Error

type ErrProtocolVersionNotSupported

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

func (ErrProtocolVersionNotSupported) Error

type Header struct {
	TransactionId uint8
	CipherSuite   CipherSuiteId
	// contains filtered or unexported fields
}

Header represents the head of an OpenSPA packet (request or response).

func HeaderDecode

func HeaderDecode(data []byte) (Header, error)

HeaderDecode converts the inputted byte slice to a header if properly formatted. The function will check the version strictly, meaning that if it does not match exactly the version of this library we will return an error.

func (*Header) Encode

func (header *Header) Encode() ([]byte, error)

Encode encodes the header struct into a byte slice. If the header version specified is larger than the one specified in the source, return an error. Checks that the encryption method is supported as well, otherwise return an error.

func (*Header) Equal

func (header *Header) Equal(h Header) bool

Equal returns true if the supplied header is semantically equal to the structs header, otherwise false.

func (*Header) SetType

func (header *Header) SetType(pduType PDUType)

func (*Header) SetVersion

func (header *Header) SetVersion(version int)

func (*Header) Type

func (header *Header) Type() PDUType

func (*Header) Version

func (header *Header) Version() int

type InternetProtocolNumber

type InternetProtocolNumber uint8

InternetProtocolNumber is the protocol found in the IPv4 header field Protocol. See: https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml

const (
	ProtocolICMP   InternetProtocolNumber = 1
	ProtocolIPV4   InternetProtocolNumber = 4
	ProtocolTCP    InternetProtocolNumber = 6
	ProtocolUDP    InternetProtocolNumber = 17
	ProtocolICMPv6 InternetProtocolNumber = 58
)

func InternetProtocolNumberSupported

func InternetProtocolNumberSupported() []InternetProtocolNumber

InternetProtocolNumberSupported returns a slice of InternetProtocolNumber that are supported.

func (InternetProtocolNumber) ToBin

func (i InternetProtocolNumber) ToBin() byte

type Nonce

type Nonce []byte

func RandomNonce

func RandomNonce() (Nonce, error)

type PDU

type PDU interface {
}

type PDUType

type PDUType uint8
const (
	PDURequestType  PDUType = 0x0
	PDUResponseType PDUType = 0x1
)

func NewPDUType

func NewPDUType(b byte) PDUType

func (PDUType) Byte

func (t PDUType) Byte() byte

type PublicIPv4Resolver

type PublicIPv4Resolver struct {
	// Endpoint should be a URL (preferably HTTPS) that will return a JSON response with a
	// field `ip` or `ipv4` (case-insensitive).
	Endpoint string
}

PublicIPv4Resolver resolved the callers public IPv4 address. This is particularly useful to resolve the public IP in case the client is behind a NAT.

func NewDefaultPublicIPv4Resolver

func NewDefaultPublicIPv4Resolver() PublicIPv4Resolver

func NewPublicIPv4Resolver

func NewPublicIPv4Resolver(endpoint string) PublicIPv4Resolver

func (*PublicIPv4Resolver) Fetch

func (r *PublicIPv4Resolver) Fetch() (net.IP, error)

type RSA_AES_128_CBC_With_RSA_SHA256

type RSA_AES_128_CBC_With_RSA_SHA256 struct {
	ServerPubKey  *rsa.PublicKey
	ClientPrivKey *rsa.PrivateKey
}

func (*RSA_AES_128_CBC_With_RSA_SHA256) CipherSuiteId

func (*RSA_AES_128_CBC_With_RSA_SHA256) Decrypt

func (r *RSA_AES_128_CBC_With_RSA_SHA256) Decrypt(ciphertext []byte) (plaintext []byte, err error)

func (*RSA_AES_128_CBC_With_RSA_SHA256) Encrypt

func (r *RSA_AES_128_CBC_With_RSA_SHA256) Encrypt(plaintext []byte) (ciphertext []byte, err error)

func (*RSA_AES_128_CBC_With_RSA_SHA256) Sign

func (r *RSA_AES_128_CBC_With_RSA_SHA256) Sign(data []byte) (signature []byte, err error)

func (*RSA_AES_128_CBC_With_RSA_SHA256) Verify

func (r *RSA_AES_128_CBC_With_RSA_SHA256) Verify(text, signature []byte) (valid bool, err error)

type Request

type Request struct {
	Head Header
	Body RequestBody

	Signature []byte
}

Request represents an OpenSPA Request. Either create a Request struct using CraftRequest() or craft it yourself. Then you need to call the Request function Sign().

func CraftRequest

func CraftRequest(data RequestData, cipherId CipherSuiteId) (*Request, error)

CraftRequest creates a Request struct without signing and encrypting it.

func (*Request) SignAndEncrypt

func (r *Request) SignAndEncrypt(c CipherSuite) ([]byte, error)

SignAndEncrypt signs the request, encrypts the request and returns the final full packet represented in binary as a byte slice.

type RequestBody

type RequestBody struct {
	Timestamp      time.Time
	ClientDeviceID string
	Nonce          Nonce

	Protocol  InternetProtocolNumber
	StartPort uint16
	EndPort   uint16

	ClientPublicIP  net.IP
	ServerPublicIP  net.IP
	ClientBehindNat bool

	TlvValues []byte
}

RequestBody represents the body of the OpenSPA request. It contains low level fields that should generally be filled by higher level functions, such as CraftRequest(). RequestBody does not contain the signature, this is left for the Request struct.

func (*RequestBody) Encode

func (body *RequestBody) Encode() ([]byte, error)

Encode encodes the packet body according to the OpenSPA specification.

type RequestData

type RequestData struct {
	ClientDeviceID string

	Protocol  InternetProtocolNumber
	StartPort uint16
	EndPort   uint16

	ClientPublicIP  net.IP
	ServerPublicIP  net.IP
	ClientBehindNat bool
}

RequestData contains fields that will be used to generate a Request - i.e. higher level construct to generate lower level RequestBody struct.

type Response

type Response struct {
	Header Header
	Body   ResponseBody
}

type ResponseBody

type ResponseBody struct {
	Timestamp time.Time
	Nonce     Nonce
	Protocol  InternetProtocolNumber
	StartPort uint16
	EndPort   uint16
	Duration  time.Duration
	Signature []byte
}

func (*ResponseBody) Encode

func (body *ResponseBody) Encode() ([]byte, error)

Encode encodes the response packet body according to the OpenSPA specification.

type ResponseData

type ResponseData struct {
	CipherSuite CipherSuiteId
	Protocol    InternetProtocolNumber
	StartPort   uint16
	EndPort     uint16
	Duration    time.Duration
}

type TLVContainer

type TLVContainer interface {
	GetByte(typeKey uint16) (b byte, exists bool)
	GetBytes(typeKey uint16) (b []byte, exists bool)

	SetByte(typeKey uint16, value byte)
	SetBytes(typeKey uint16, value []byte)

	BytesBuffer() *bytes.Buffer
	BytesBufferLen() int

	NoEntries() int
}

func NewTLVContainer

func NewTLVContainer(b []byte) (TLVContainer, error)

type TLVType

type TLVType uint16
const (
	TypeEncryptedData     TLVType = 0x01
	TypeTimestamp         TLVType = 0x02
	TypeClientDeviceUUID  TLVType = 0x03
	TypeFirewallProtocol  TLVType = 0x04
	TypeFirewallPortStart TLVType = 0x05
	TypeFirewallPortEnd   TLVType = 0x06
	TypeClientPublicIPv6  TLVType = 0x07
	TypeServerPublicIPv6  TLVType = 0x08
	TypeClientPublicIPv4  TLVType = 0x09
	TypeServerPublicIPv4  TLVType = 0x0A
	TypeClientBehindNAT   TLVType = 0x0B
	TypeSignature         TLVType = 0x0C
	TypeNonce             TLVType = 0x0D
	TypeDuration          TLVType = 0x0E
	TypeClientUsername    TLVType = 0x0F
)

func (TLVType) Byte

func (t TLVType) Byte() []byte

func (TLVType) Hex

func (t TLVType) Hex() string

Hex returns the type as a hexadecimal encoded string without the 0x prefix. The letters A-F will be upper-case.

Directories

Path Synopsis
Package tlv21 implements TLV with 2 bytes for the type and 1 byte for the length.
Package tlv21 implements TLV with 2 bytes for the type and 1 byte for the length.
Package tlv8 implements TLV with 1 bytes for the type and 1 byte for the length.
Package tlv8 implements TLV with 1 bytes for the type and 1 byte for the length.

Jump to

Keyboard shortcuts

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