mirror of
https://github.com/go-gitea/gitea.git
synced 2026-09-23 21:23:41 +09:00
Support webauthn (#17957)
Migrate from U2F to Webauthn Co-authored-by: Andrew Thornton <art27@cantab.net> Co-authored-by: 6543 <6543@obermui.de> Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
co-authored by
Andrew Thornton
6543
wxiaoguang
parent
8808293247
commit
35c3553870
+196
@@ -0,0 +1,196 @@
|
||||
// Copyright (c) Faye Amacker. All rights reserved.
|
||||
// Licensed under the MIT License. See LICENSE in the project root for license information.
|
||||
|
||||
package cbor
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// Decoder reads and decodes CBOR values from an input stream.
|
||||
type Decoder struct {
|
||||
r io.Reader
|
||||
buf []byte
|
||||
d decodeState
|
||||
off int // start of unread data in buf
|
||||
bytesRead int
|
||||
}
|
||||
|
||||
// NewDecoder returns a new decoder that reads from r using the default decoding options.
|
||||
func NewDecoder(r io.Reader) *Decoder {
|
||||
return defaultDecMode.NewDecoder(r)
|
||||
}
|
||||
|
||||
// Decode reads the next CBOR-encoded value from its input and stores it in
|
||||
// the value pointed to by v.
|
||||
func (dec *Decoder) Decode(v interface{}) error {
|
||||
if len(dec.buf) == dec.off {
|
||||
if n, err := dec.read(); n == 0 {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
dec.d.reset(dec.buf[dec.off:])
|
||||
err := dec.d.value(v)
|
||||
dec.off += dec.d.off
|
||||
dec.bytesRead += dec.d.off
|
||||
if err != nil {
|
||||
if err != io.ErrUnexpectedEOF {
|
||||
return err
|
||||
}
|
||||
// Need to read more data.
|
||||
if n, e := dec.read(); n == 0 {
|
||||
return e
|
||||
}
|
||||
return dec.Decode(v)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// NumBytesRead returns the number of bytes read.
|
||||
func (dec *Decoder) NumBytesRead() int {
|
||||
return dec.bytesRead
|
||||
}
|
||||
|
||||
func (dec *Decoder) read() (int, error) {
|
||||
// Copy unread data over read data and reset off to 0.
|
||||
if dec.off > 0 {
|
||||
n := copy(dec.buf, dec.buf[dec.off:])
|
||||
dec.buf = dec.buf[:n]
|
||||
dec.off = 0
|
||||
}
|
||||
|
||||
// Grow buf if needed.
|
||||
const minRead = 512
|
||||
if cap(dec.buf)-len(dec.buf) < minRead {
|
||||
newBuf := make([]byte, len(dec.buf), 2*cap(dec.buf)+minRead)
|
||||
copy(newBuf, dec.buf)
|
||||
dec.buf = newBuf
|
||||
}
|
||||
|
||||
// Read from reader and reslice buf.
|
||||
n, err := dec.r.Read(dec.buf[len(dec.buf):cap(dec.buf)])
|
||||
dec.buf = dec.buf[0 : len(dec.buf)+n]
|
||||
return n, err
|
||||
}
|
||||
|
||||
// Encoder writes CBOR values to an output stream.
|
||||
type Encoder struct {
|
||||
w io.Writer
|
||||
em *encMode
|
||||
e *encodeState
|
||||
indefTypes []cborType
|
||||
}
|
||||
|
||||
// NewEncoder returns a new encoder that writes to w using the default encoding options.
|
||||
func NewEncoder(w io.Writer) *Encoder {
|
||||
return defaultEncMode.NewEncoder(w)
|
||||
}
|
||||
|
||||
// Encode writes the CBOR encoding of v to the stream.
|
||||
func (enc *Encoder) Encode(v interface{}) error {
|
||||
if len(enc.indefTypes) > 0 && v != nil {
|
||||
indefType := enc.indefTypes[len(enc.indefTypes)-1]
|
||||
if indefType == cborTypeTextString {
|
||||
k := reflect.TypeOf(v).Kind()
|
||||
if k != reflect.String {
|
||||
return errors.New("cbor: cannot encode item type " + k.String() + " for indefinite-length text string")
|
||||
}
|
||||
} else if indefType == cborTypeByteString {
|
||||
t := reflect.TypeOf(v)
|
||||
k := t.Kind()
|
||||
if (k != reflect.Array && k != reflect.Slice) || t.Elem().Kind() != reflect.Uint8 {
|
||||
return errors.New("cbor: cannot encode item type " + k.String() + " for indefinite-length byte string")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
err := encode(enc.e, enc.em, reflect.ValueOf(v))
|
||||
if err == nil {
|
||||
_, err = enc.e.WriteTo(enc.w)
|
||||
}
|
||||
enc.e.Reset()
|
||||
return err
|
||||
}
|
||||
|
||||
// StartIndefiniteByteString starts byte string encoding of indefinite length.
|
||||
// Subsequent calls of (*Encoder).Encode() encodes definite length byte strings
|
||||
// ("chunks") as one continguous string until EndIndefinite is called.
|
||||
func (enc *Encoder) StartIndefiniteByteString() error {
|
||||
return enc.startIndefinite(cborTypeByteString)
|
||||
}
|
||||
|
||||
// StartIndefiniteTextString starts text string encoding of indefinite length.
|
||||
// Subsequent calls of (*Encoder).Encode() encodes definite length text strings
|
||||
// ("chunks") as one continguous string until EndIndefinite is called.
|
||||
func (enc *Encoder) StartIndefiniteTextString() error {
|
||||
return enc.startIndefinite(cborTypeTextString)
|
||||
}
|
||||
|
||||
// StartIndefiniteArray starts array encoding of indefinite length.
|
||||
// Subsequent calls of (*Encoder).Encode() encodes elements of the array
|
||||
// until EndIndefinite is called.
|
||||
func (enc *Encoder) StartIndefiniteArray() error {
|
||||
return enc.startIndefinite(cborTypeArray)
|
||||
}
|
||||
|
||||
// StartIndefiniteMap starts array encoding of indefinite length.
|
||||
// Subsequent calls of (*Encoder).Encode() encodes elements of the map
|
||||
// until EndIndefinite is called.
|
||||
func (enc *Encoder) StartIndefiniteMap() error {
|
||||
return enc.startIndefinite(cborTypeMap)
|
||||
}
|
||||
|
||||
// EndIndefinite closes last opened indefinite length value.
|
||||
func (enc *Encoder) EndIndefinite() error {
|
||||
if len(enc.indefTypes) == 0 {
|
||||
return errors.New("cbor: cannot encode \"break\" code outside indefinite length values")
|
||||
}
|
||||
_, err := enc.w.Write([]byte{0xff})
|
||||
if err == nil {
|
||||
enc.indefTypes = enc.indefTypes[:len(enc.indefTypes)-1]
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
var cborIndefHeader = map[cborType][]byte{
|
||||
cborTypeByteString: {0x5f},
|
||||
cborTypeTextString: {0x7f},
|
||||
cborTypeArray: {0x9f},
|
||||
cborTypeMap: {0xbf},
|
||||
}
|
||||
|
||||
func (enc *Encoder) startIndefinite(typ cborType) error {
|
||||
if enc.em.indefLength == IndefLengthForbidden {
|
||||
return &IndefiniteLengthError{typ}
|
||||
}
|
||||
_, err := enc.w.Write(cborIndefHeader[typ])
|
||||
if err == nil {
|
||||
enc.indefTypes = append(enc.indefTypes, typ)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// RawMessage is a raw encoded CBOR value. It implements Marshaler and
|
||||
// Unmarshaler interfaces and can be used to delay CBOR decoding or
|
||||
// precompute a CBOR encoding.
|
||||
type RawMessage []byte
|
||||
|
||||
// MarshalCBOR returns m as the CBOR encoding of m.
|
||||
func (m RawMessage) MarshalCBOR() ([]byte, error) {
|
||||
if len(m) == 0 {
|
||||
return cborNil, nil
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// UnmarshalCBOR sets *m to a copy of data.
|
||||
func (m *RawMessage) UnmarshalCBOR(data []byte) error {
|
||||
if m == nil {
|
||||
return errors.New("cbor.RawMessage: UnmarshalCBOR on nil pointer")
|
||||
}
|
||||
*m = append((*m)[0:0], data...)
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user