Documentation ¶
Index ¶
- Constants
- Variables
- func CipherSuiteIsSupported(c CipherSuiteId) bool
- func NewRequest(data RequestData, c CipherSuite) ([]byte, error)
- func TestingRsaKeyPair1() (*rsa.PrivateKey, *rsa.PublicKey)
- func TestingRsaKeyPair2() (*rsa.PrivateKey, *rsa.PublicKey)
- type CipherSuite
- type CipherSuiteId
- type CryptoDecryptionMethod
- type CryptoEncryptionMethod
- type CryptoMethodMock
- func (_ CryptoMethodMock) CipherSuiteId() CipherSuiteId
- func (_ CryptoMethodMock) Decrypt(ciphertext []byte) (plaintext []byte, err error)
- func (_ CryptoMethodMock) Encrypt(plaintext []byte) (ciphertext []byte, err error)
- func (_ CryptoMethodMock) Sign(text []byte) (signature []byte, err error)
- func (_ CryptoMethodMock) Verify(text, signature []byte) (valid bool, err error)
- type CryptoSignatureMethod
- type CryptoSignatureVerificationMethod
- type ErrCipherSuiteNotSupported
- type ErrProtocolVersionNotSupported
- type Header
- type InternetProtocolNumber
- type Nonce
- type PDU
- type PDUType
- type PublicIPv4Resolver
- type RSA_AES_128_CBC_With_RSA_SHA256
- func (r *RSA_AES_128_CBC_With_RSA_SHA256) CipherSuiteId() CipherSuiteId
- func (r *RSA_AES_128_CBC_With_RSA_SHA256) Decrypt(ciphertext []byte) (plaintext []byte, err error)
- func (r *RSA_AES_128_CBC_With_RSA_SHA256) Encrypt(plaintext []byte) (ciphertext []byte, err error)
- func (r *RSA_AES_128_CBC_With_RSA_SHA256) Sign(data []byte) (signature []byte, err error)
- func (r *RSA_AES_128_CBC_With_RSA_SHA256) Verify(text, signature []byte) (valid bool, err error)
- type Request
- type RequestBody
- type RequestData
- type Response
- type ResponseBody
- type ResponseData
- type TLVContainer
- type TLVType
Constants ¶
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) )
const ( Version = 2 // version of the protocol PDUMaxSize = 1408 // bytes (UDP payload i.e. OpenSPA header + body) BodyMaxSize = PDUMaxSize - HeaderSize // bytes )
const HeaderSize = 8 // bytes
const (
PublicIPv4ResolverDefaultEndpoint = "https://ipv4.openspa.org"
)
const (
RequestPacketBodySize = 68 // bytes, packet body size without the signature and TLV values
)
const (
ResponsePacketBodySize = 24 // bytes
)
Variables ¶
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") )
var (
ErrBadIP = errors.New("bad ip address")
)
var ErrHeaderTooShort = errors.New("header too short")
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 CipherSuite ¶
type CipherSuite interface { CryptoEncryptionMethod CryptoDecryptionMethod CryptoSignatureMethod CryptoSignatureVerificationMethod CipherSuiteId() CipherSuiteId }
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 CryptoEncryptionMethod ¶
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)
type CryptoSignatureMethod ¶
type ErrCipherSuiteNotSupported ¶
type ErrCipherSuiteNotSupported struct {
// contains filtered or unexported fields
}
func (ErrCipherSuiteNotSupported) Error ¶
func (e ErrCipherSuiteNotSupported) Error() string
type ErrProtocolVersionNotSupported ¶
type ErrProtocolVersionNotSupported struct {
// contains filtered or unexported fields
}
func (ErrProtocolVersionNotSupported) Error ¶
func (e ErrProtocolVersionNotSupported) Error() string
type Header ¶
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 ¶
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 ¶
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 ¶
Equal returns true if the supplied header is semantically equal to the structs header, otherwise false.
func (*Header) SetVersion ¶
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 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
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 (r *RSA_AES_128_CBC_With_RSA_SHA256) CipherSuiteId() 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)
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 )
Source Files ¶
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. |