1
0

Update module lib/pq to v1.6.0 (#572)

Update module lib/pq to v1.6.0

Reviewed-on: https://kolaente.dev/vikunja/api/pulls/572
This commit is contained in:
renovate
2020-05-29 17:47:28 +00:00
committed by konrad
parent 5a04f1ecf4
commit 54b18b3c59
161 changed files with 19472 additions and 7 deletions

View File

@ -0,0 +1,174 @@
package gssapi
import (
"bytes"
"crypto/hmac"
"encoding/binary"
"encoding/hex"
"errors"
"fmt"
"github.com/jcmturner/gokrb5/v8/crypto"
"github.com/jcmturner/gokrb5/v8/iana/keyusage"
"github.com/jcmturner/gokrb5/v8/types"
)
// RFC 4121, section 4.2.6.1
const (
// MICTokenFlagSentByAcceptor - this flag indicates the sender is the context acceptor. When not set, it indicates the sender is the context initiator
MICTokenFlagSentByAcceptor = 1 << iota
// MICTokenFlagSealed - this flag indicates confidentiality is provided for. It SHALL NOT be set in MIC tokens
MICTokenFlagSealed
// MICTokenFlagAcceptorSubkey - a subkey asserted by the context acceptor is used to protect the message
MICTokenFlagAcceptorSubkey
)
const (
micHdrLen = 16 // Length of the MIC Token's header
)
// MICToken represents a GSS API MIC token, as defined in RFC 4121.
// It contains the header fields, the payload (this is not transmitted) and
// the checksum, and provides the logic for converting to/from bytes plus
// computing and verifying checksums
type MICToken struct {
// const GSS Token ID: 0x0404
Flags byte // contains three flags: acceptor, sealed, acceptor subkey
// const Filler: 0xFF 0xFF 0xFF 0xFF 0xFF
SndSeqNum uint64 // sender's sequence number. big-endian
Payload []byte // your data! :)
Checksum []byte // checksum of { payload | header }
}
// Return the 2 bytes identifying a GSS API MIC token
func getGSSMICTokenID() *[2]byte {
return &[2]byte{0x04, 0x04}
}
// Return the filler bytes used in header
func fillerBytes() *[5]byte {
return &[5]byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF}
}
// Marshal the MICToken into a byte slice.
// The payload should have been set and the checksum computed, otherwise an error is returned.
func (mt *MICToken) Marshal() ([]byte, error) {
if mt.Checksum == nil {
return nil, errors.New("checksum has not been set")
}
bytes := make([]byte, micHdrLen+len(mt.Checksum))
copy(bytes[0:micHdrLen], mt.getMICChecksumHeader()[:])
copy(bytes[micHdrLen:], mt.Checksum)
return bytes, nil
}
// SetChecksum uses the passed encryption key and key usage to compute the checksum over the payload and
// the header, and sets the Checksum field of this MICToken.
// If the payload has not been set or the checksum has already been set, an error is returned.
func (mt *MICToken) SetChecksum(key types.EncryptionKey, keyUsage uint32) error {
if mt.Checksum != nil {
return errors.New("checksum has already been computed")
}
checksum, err := mt.checksum(key, keyUsage)
if err != nil {
return err
}
mt.Checksum = checksum
return nil
}
// Compute and return the checksum of this token, computed using the passed key and key usage.
// Note: This will NOT update the struct's Checksum field.
func (mt *MICToken) checksum(key types.EncryptionKey, keyUsage uint32) ([]byte, error) {
if mt.Payload == nil {
return nil, errors.New("cannot compute checksum with uninitialized payload")
}
d := make([]byte, micHdrLen+len(mt.Payload))
copy(d[0:], mt.Payload)
copy(d[len(mt.Payload):], mt.getMICChecksumHeader())
encType, err := crypto.GetEtype(key.KeyType)
if err != nil {
return nil, err
}
return encType.GetChecksumHash(key.KeyValue, d, keyUsage)
}
// Build a header suitable for a checksum computation
func (mt *MICToken) getMICChecksumHeader() []byte {
header := make([]byte, micHdrLen)
copy(header[0:2], getGSSMICTokenID()[:])
header[2] = mt.Flags
copy(header[3:8], fillerBytes()[:])
binary.BigEndian.PutUint64(header[8:16], mt.SndSeqNum)
return header
}
// Verify computes the token's checksum with the provided key and usage,
// and compares it to the checksum present in the token.
// In case of any failure, (false, err) is returned, with err an explanatory error.
func (mt *MICToken) Verify(key types.EncryptionKey, keyUsage uint32) (bool, error) {
computed, err := mt.checksum(key, keyUsage)
if err != nil {
return false, err
}
if !hmac.Equal(computed, mt.Checksum) {
return false, fmt.Errorf(
"checksum mismatch. Computed: %s, Contained in token: %s",
hex.EncodeToString(computed), hex.EncodeToString(mt.Checksum))
}
return true, nil
}
// Unmarshal bytes into the corresponding MICToken.
// If expectFromAcceptor is true we expect the token to have been emitted by the gss acceptor,
// and will check the according flag, returning an error if the token does not match the expectation.
func (mt *MICToken) Unmarshal(b []byte, expectFromAcceptor bool) error {
if len(b) < micHdrLen {
return errors.New("bytes shorter than header length")
}
if !bytes.Equal(getGSSMICTokenID()[:], b[0:2]) {
return fmt.Errorf("wrong Token ID, Expected %s, was %s",
hex.EncodeToString(getGSSMICTokenID()[:]),
hex.EncodeToString(b[0:2]))
}
flags := b[2]
isFromAcceptor := flags&MICTokenFlagSentByAcceptor != 0
if isFromAcceptor && !expectFromAcceptor {
return errors.New("unexpected acceptor flag is set: not expecting a token from the acceptor")
}
if !isFromAcceptor && expectFromAcceptor {
return errors.New("unexpected acceptor flag is not set: expecting a token from the acceptor, not in the initiator")
}
if !bytes.Equal(b[3:8], fillerBytes()[:]) {
return fmt.Errorf("unexpected filler bytes: expecting %s, was %s",
hex.EncodeToString(fillerBytes()[:]),
hex.EncodeToString(b[3:8]))
}
mt.Flags = flags
mt.SndSeqNum = binary.BigEndian.Uint64(b[8:16])
mt.Checksum = b[micHdrLen:]
return nil
}
// NewInitiatorMICToken builds a new initiator token (acceptor flag will be set to 0) and computes the authenticated checksum.
// Other flags are set to 0.
// Note that in certain circumstances you may need to provide a sequence number that has been defined earlier.
// This is currently not supported.
func NewInitiatorMICToken(payload []byte, key types.EncryptionKey) (*MICToken, error) {
token := MICToken{
Flags: 0x00,
SndSeqNum: 0,
Payload: payload,
}
if err := token.SetChecksum(key, keyusage.GSSAPI_INITIATOR_SIGN); err != nil {
return nil, err
}
return &token, nil
}

20
vendor/github.com/jcmturner/gokrb5/v8/gssapi/README.md generated vendored Normal file
View File

@ -0,0 +1,20 @@
# Notes on GSS-API Negotiation Mechanism
https://tools.ietf.org/html/rfc4178
Client sends an initial negotiation message to the server which specifies the list of mechanisms
the client can support in order of decreasing preference.
This message is generated with the ``NewNegTokenInitKrb5`` method.
The message generated by this function specifies only a kerberos v5 mechanism is supported.
The RFC states that this message can optionally contain the initial mechanism token
for the preferred mechanism (KRB5 in this case) of the client. The ``NewNegTokenInitKrb5``
includes this in the message.
The server side responds to this message with a one of four messages:
| Message Type/State | Description |
|--------------------|-------------|
| accept-completed | indicates that the initiator-selected mechanism was acceptable to the target, and that the security mechanism token embedded in the first negotiation message was sufficient to complete the authentication |
| accept-incomplete | At least one more message is needed from the client to establish security context. |
| reject | Negotiation is being terminated. |
| request-mic | (this state can only be present in the first reply message from the target) indicates that the MIC token exchange is REQUIRED if per-message integrity services are available |

View File

@ -0,0 +1,25 @@
package gssapi
import "github.com/jcmturner/gofork/encoding/asn1"
// GSS-API context flags assigned numbers.
const (
ContextFlagDeleg = 1
ContextFlagMutual = 2
ContextFlagReplay = 4
ContextFlagSequence = 8
ContextFlagConf = 16
ContextFlagInteg = 32
ContextFlagAnon = 64
)
// ContextFlags flags for GSSAPI
type ContextFlags asn1.BitString
// NewContextFlags creates a new ContextFlags instance.
func NewContextFlags() ContextFlags {
var c ContextFlags
c.BitLength = 32
c.Bytes = make([]byte, 4)
return c
}

202
vendor/github.com/jcmturner/gokrb5/v8/gssapi/gssapi.go generated vendored Normal file
View File

@ -0,0 +1,202 @@
// Package gssapi implements Generic Security Services Application Program Interface required for SPNEGO kerberos authentication.
package gssapi
import (
"context"
"fmt"
"github.com/jcmturner/gofork/encoding/asn1"
)
// GSS-API OID names
const (
// GSS-API OID names
OIDKRB5 OIDName = "KRB5" // MechType OID for Kerberos 5
OIDMSLegacyKRB5 OIDName = "MSLegacyKRB5" // MechType OID for Kerberos 5
OIDSPNEGO OIDName = "SPNEGO"
OIDGSSIAKerb OIDName = "GSSIAKerb" // Indicates the client cannot get a service ticket and asks the server to serve as an intermediate to the target KDC. http://k5wiki.kerberos.org/wiki/Projects/IAKERB#IAKERB_mech
)
// GSS-API status values
const (
StatusBadBindings = 1 << iota
StatusBadMech
StatusBadName
StatusBadNameType
StatusBadStatus
StatusBadSig
StatusBadMIC
StatusContextExpired
StatusCredentialsExpired
StatusDefectiveCredential
StatusDefectiveToken
StatusFailure
StatusNoContext
StatusNoCred
StatusBadQOP
StatusUnauthorized
StatusUnavailable
StatusDuplicateElement
StatusNameNotMN
StatusComplete
StatusContinueNeeded
StatusDuplicateToken
StatusOldToken
StatusUnseqToken
StatusGapToken
)
// ContextToken is an interface for a GSS-API context token.
type ContextToken interface {
Marshal() ([]byte, error)
Unmarshal(b []byte) error
Verify() (bool, Status)
Context() context.Context
}
/*
CREDENTIAL MANAGEMENT
GSS_Acquire_cred acquire credentials for use
GSS_Release_cred release credentials after use
GSS_Inquire_cred display information about credentials
GSS_Add_cred construct credentials incrementally
GSS_Inquire_cred_by_mech display per-mechanism credential information
CONTEXT-LEVEL CALLS
GSS_Init_sec_context initiate outbound security context
GSS_Accept_sec_context accept inbound security context
GSS_Delete_sec_context flush context when no longer needed
GSS_Process_context_token process received control token on context
GSS_Context_time indicate validity time remaining on context
GSS_Inquire_context display information about context
GSS_Wrap_size_limit determine GSS_Wrap token size limit
GSS_Export_sec_context transfer context to other process
GSS_Import_sec_context import transferred context
PER-MESSAGE CALLS
GSS_GetMIC apply integrity check, receive as token separate from message
GSS_VerifyMIC validate integrity check token along with message
GSS_Wrap sign, optionally encrypt, encapsulate
GSS_Unwrap decapsulate, decrypt if needed, validate integrity check
SUPPORT CALLS
GSS_Display_status translate status codes to printable form
GSS_Indicate_mechs indicate mech_types supported on local system
GSS_Compare_name compare two names for equality
GSS_Display_name translate name to printable form
GSS_Import_name convert printable name to normalized form
GSS_Release_name free storage of normalized-form name
GSS_Release_buffer free storage of general GSS-allocated object
GSS_Release_OID_set free storage of OID set object
GSS_Create_empty_OID_set create empty OID set
GSS_Add_OID_set_member add member to OID set
GSS_Test_OID_set_member test if OID is member of OID set
GSS_Inquire_names_for_mech indicate name types supported by mechanism
GSS_Inquire_mechs_for_name indicates mechanisms supporting name type
GSS_Canonicalize_name translate name to per-mechanism form
GSS_Export_name externalize per-mechanism name
GSS_Duplicate_name duplicate name object
*/
// Mechanism is the GSS-API interface for authentication mechanisms.
type Mechanism interface {
OID() asn1.ObjectIdentifier
AcquireCred() error // acquire credentials for use (eg. AS exchange for KRB5)
InitSecContext() (ContextToken, error) // initiate outbound security context (eg TGS exchange builds AP_REQ to go into ContextToken to send to service)
AcceptSecContext(ct ContextToken) (bool, context.Context, Status) // service verifies the token server side to establish a context
MIC() MICToken // apply integrity check, receive as token separate from message
VerifyMIC(mt MICToken) (bool, error) // validate integrity check token along with message
Wrap(msg []byte) WrapToken // sign, optionally encrypt, encapsulate
Unwrap(wt WrapToken) []byte // decapsulate, decrypt if needed, validate integrity check
}
// OIDName is the type for defined GSS-API OIDs.
type OIDName string
// OID returns the OID for the provided OID name.
func (o OIDName) OID() asn1.ObjectIdentifier {
switch o {
case OIDSPNEGO:
return asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 2}
case OIDKRB5:
return asn1.ObjectIdentifier{1, 2, 840, 113554, 1, 2, 2}
case OIDMSLegacyKRB5:
return asn1.ObjectIdentifier{1, 2, 840, 48018, 1, 2, 2}
case OIDGSSIAKerb:
return asn1.ObjectIdentifier{1, 3, 6, 1, 5, 2, 5}
}
return asn1.ObjectIdentifier{}
}
// Status is the GSS-API status and implements the error interface.
type Status struct {
Code int
Message string
}
// Error returns the Status description.
func (s Status) Error() string {
var str string
switch s.Code {
case StatusBadBindings:
str = "channel binding mismatch"
case StatusBadMech:
str = "unsupported mechanism requested"
case StatusBadName:
str = "invalid name provided"
case StatusBadNameType:
str = "name of unsupported type provided"
case StatusBadStatus:
str = "invalid input status selector"
case StatusBadSig:
str = "token had invalid integrity check"
case StatusBadMIC:
str = "preferred alias for GSS_S_BAD_SIG"
case StatusContextExpired:
str = "specified security context expired"
case StatusCredentialsExpired:
str = "expired credentials detected"
case StatusDefectiveCredential:
str = "defective credential detected"
case StatusDefectiveToken:
str = "defective token detected"
case StatusFailure:
str = "failure, unspecified at GSS-API level"
case StatusNoContext:
str = "no valid security context specified"
case StatusNoCred:
str = "no valid credentials provided"
case StatusBadQOP:
str = "unsupported QOP valu"
case StatusUnauthorized:
str = "operation unauthorized"
case StatusUnavailable:
str = "operation unavailable"
case StatusDuplicateElement:
str = "duplicate credential element requested"
case StatusNameNotMN:
str = "name contains multi-mechanism elements"
case StatusComplete:
str = "normal completion"
case StatusContinueNeeded:
str = "continuation call to routine required"
case StatusDuplicateToken:
str = "duplicate per-message token detected"
case StatusOldToken:
str = "timed-out per-message token detected"
case StatusUnseqToken:
str = "reordered (early) per-message token detected"
case StatusGapToken:
str = "skipped predecessor token(s) detected"
default:
str = "unknown GSS-API error status"
}
if s.Message != "" {
return fmt.Sprintf("%s: %s", str, s.Message)
}
return str
}

View File

@ -0,0 +1,193 @@
package gssapi
import (
"bytes"
"crypto/hmac"
"encoding/binary"
"encoding/hex"
"errors"
"fmt"
"github.com/jcmturner/gokrb5/v8/crypto"
"github.com/jcmturner/gokrb5/v8/iana/keyusage"
"github.com/jcmturner/gokrb5/v8/types"
)
// RFC 4121, section 4.2.6.2
const (
HdrLen = 16 // Length of the Wrap Token's header
FillerByte byte = 0xFF
)
// WrapToken represents a GSS API Wrap token, as defined in RFC 4121.
// It contains the header fields, the payload and the checksum, and provides
// the logic for converting to/from bytes plus computing and verifying checksums
type WrapToken struct {
// const GSS Token ID: 0x0504
Flags byte // contains three flags: acceptor, sealed, acceptor subkey
// const Filler: 0xFF
EC uint16 // checksum length. big-endian
RRC uint16 // right rotation count. big-endian
SndSeqNum uint64 // sender's sequence number. big-endian
Payload []byte // your data! :)
CheckSum []byte // authenticated checksum of { payload | header }
}
// Return the 2 bytes identifying a GSS API Wrap token
func getGssWrapTokenId() *[2]byte {
return &[2]byte{0x05, 0x04}
}
// Marshal the WrapToken into a byte slice.
// The payload should have been set and the checksum computed, otherwise an error is returned.
func (wt *WrapToken) Marshal() ([]byte, error) {
if wt.CheckSum == nil {
return nil, errors.New("checksum has not been set")
}
if wt.Payload == nil {
return nil, errors.New("payload has not been set")
}
pldOffset := HdrLen // Offset of the payload in the token
chkSOffset := HdrLen + len(wt.Payload) // Offset of the checksum in the token
bytes := make([]byte, chkSOffset+int(wt.EC))
copy(bytes[0:], getGssWrapTokenId()[:])
bytes[2] = wt.Flags
bytes[3] = FillerByte
binary.BigEndian.PutUint16(bytes[4:6], wt.EC)
binary.BigEndian.PutUint16(bytes[6:8], wt.RRC)
binary.BigEndian.PutUint64(bytes[8:16], wt.SndSeqNum)
copy(bytes[pldOffset:], wt.Payload)
copy(bytes[chkSOffset:], wt.CheckSum)
return bytes, nil
}
// SetCheckSum uses the passed encryption key and key usage to compute the checksum over the payload and
// the header, and sets the CheckSum field of this WrapToken.
// If the payload has not been set or the checksum has already been set, an error is returned.
func (wt *WrapToken) SetCheckSum(key types.EncryptionKey, keyUsage uint32) error {
if wt.Payload == nil {
return errors.New("payload has not been set")
}
if wt.CheckSum != nil {
return errors.New("checksum has already been computed")
}
chkSum, cErr := wt.computeCheckSum(key, keyUsage)
if cErr != nil {
return cErr
}
wt.CheckSum = chkSum
return nil
}
// ComputeCheckSum computes and returns the checksum of this token, computed using the passed key and key usage.
// Note: This will NOT update the struct's Checksum field.
func (wt *WrapToken) computeCheckSum(key types.EncryptionKey, keyUsage uint32) ([]byte, error) {
if wt.Payload == nil {
return nil, errors.New("cannot compute checksum with uninitialized payload")
}
// Build a slice containing { payload | header }
checksumMe := make([]byte, HdrLen+len(wt.Payload))
copy(checksumMe[0:], wt.Payload)
copy(checksumMe[len(wt.Payload):], getChecksumHeader(wt.Flags, wt.SndSeqNum))
encType, err := crypto.GetEtype(key.KeyType)
if err != nil {
return nil, err
}
return encType.GetChecksumHash(key.KeyValue, checksumMe, keyUsage)
}
// Build a header suitable for a checksum computation
func getChecksumHeader(flags byte, senderSeqNum uint64) []byte {
header := make([]byte, 16)
copy(header[0:], []byte{0x05, 0x04, flags, 0xFF, 0x00, 0x00, 0x00, 0x00})
binary.BigEndian.PutUint64(header[8:], senderSeqNum)
return header
}
// Verify computes the token's checksum with the provided key and usage,
// and compares it to the checksum present in the token.
// In case of any failure, (false, Err) is returned, with Err an explanatory error.
func (wt *WrapToken) Verify(key types.EncryptionKey, keyUsage uint32) (bool, error) {
computed, cErr := wt.computeCheckSum(key, keyUsage)
if cErr != nil {
return false, cErr
}
if !hmac.Equal(computed, wt.CheckSum) {
return false, fmt.Errorf(
"checksum mismatch. Computed: %s, Contained in token: %s",
hex.EncodeToString(computed), hex.EncodeToString(wt.CheckSum))
}
return true, nil
}
// Unmarshal bytes into the corresponding WrapToken.
// If expectFromAcceptor is true, we expect the token to have been emitted by the gss acceptor,
// and will check the according flag, returning an error if the token does not match the expectation.
func (wt *WrapToken) Unmarshal(b []byte, expectFromAcceptor bool) error {
// Check if we can read a whole header
if len(b) < 16 {
return errors.New("bytes shorter than header length")
}
// Is the Token ID correct?
if !bytes.Equal(getGssWrapTokenId()[:], b[0:2]) {
return fmt.Errorf("wrong Token ID. Expected %s, was %s",
hex.EncodeToString(getGssWrapTokenId()[:]),
hex.EncodeToString(b[0:2]))
}
// Check the acceptor flag
flags := b[2]
isFromAcceptor := flags&0x01 == 1
if isFromAcceptor && !expectFromAcceptor {
return errors.New("unexpected acceptor flag is set: not expecting a token from the acceptor")
}
if !isFromAcceptor && expectFromAcceptor {
return errors.New("expected acceptor flag is not set: expecting a token from the acceptor, not the initiator")
}
// Check the filler byte
if b[3] != FillerByte {
return fmt.Errorf("unexpected filler byte: expecting 0xFF, was %s ", hex.EncodeToString(b[3:4]))
}
checksumL := binary.BigEndian.Uint16(b[4:6])
// Sanity check on the checksum length
if int(checksumL) > len(b)-HdrLen {
return fmt.Errorf("inconsistent checksum length: %d bytes to parse, checksum length is %d", len(b), checksumL)
}
wt.Flags = flags
wt.EC = checksumL
wt.RRC = binary.BigEndian.Uint16(b[6:8])
wt.SndSeqNum = binary.BigEndian.Uint64(b[8:16])
wt.Payload = b[16 : len(b)-int(checksumL)]
wt.CheckSum = b[len(b)-int(checksumL):]
return nil
}
// NewInitiatorWrapToken builds a new initiator token (acceptor flag will be set to 0) and computes the authenticated checksum.
// Other flags are set to 0, and the RRC and sequence number are initialized to 0.
// Note that in certain circumstances you may need to provide a sequence number that has been defined earlier.
// This is currently not supported.
func NewInitiatorWrapToken(payload []byte, key types.EncryptionKey) (*WrapToken, error) {
encType, err := crypto.GetEtype(key.KeyType)
if err != nil {
return nil, err
}
token := WrapToken{
Flags: 0x00, // all zeroed out (this is a token sent by the initiator)
// Checksum size: length of output of the HMAC function, in bytes.
EC: uint16(encType.GetHMACBitLength() / 8),
RRC: 0,
SndSeqNum: 0,
Payload: payload,
}
if err := token.SetCheckSum(key, keyusage.GSSAPI_INITIATOR_SEAL); err != nil {
return nil, err
}
return &token, nil
}