forked from forgejo/forgejo
add letsencrypt to Gitea (#4189)
This commit is contained in:
parent
6c1a31ffaa
commit
b82c14b3d2
35 changed files with 4521 additions and 283 deletions
252
vendor/golang.org/x/crypto/ssh/cipher.go
generated
vendored
252
vendor/golang.org/x/crypto/ssh/cipher.go
generated
vendored
|
@ -16,6 +16,9 @@ import (
|
|||
"hash"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
|
||||
"golang.org/x/crypto/internal/chacha20"
|
||||
"golang.org/x/crypto/poly1305"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -53,78 +56,78 @@ func newRC4(key, iv []byte) (cipher.Stream, error) {
|
|||
return rc4.NewCipher(key)
|
||||
}
|
||||
|
||||
type streamCipherMode struct {
|
||||
keySize int
|
||||
ivSize int
|
||||
skip int
|
||||
createFunc func(key, iv []byte) (cipher.Stream, error)
|
||||
type cipherMode struct {
|
||||
keySize int
|
||||
ivSize int
|
||||
create func(key, iv []byte, macKey []byte, algs directionAlgorithms) (packetCipher, error)
|
||||
}
|
||||
|
||||
func (c *streamCipherMode) createStream(key, iv []byte) (cipher.Stream, error) {
|
||||
if len(key) < c.keySize {
|
||||
panic("ssh: key length too small for cipher")
|
||||
}
|
||||
if len(iv) < c.ivSize {
|
||||
panic("ssh: iv too small for cipher")
|
||||
}
|
||||
|
||||
stream, err := c.createFunc(key[:c.keySize], iv[:c.ivSize])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var streamDump []byte
|
||||
if c.skip > 0 {
|
||||
streamDump = make([]byte, 512)
|
||||
}
|
||||
|
||||
for remainingToDump := c.skip; remainingToDump > 0; {
|
||||
dumpThisTime := remainingToDump
|
||||
if dumpThisTime > len(streamDump) {
|
||||
dumpThisTime = len(streamDump)
|
||||
func streamCipherMode(skip int, createFunc func(key, iv []byte) (cipher.Stream, error)) func(key, iv []byte, macKey []byte, algs directionAlgorithms) (packetCipher, error) {
|
||||
return func(key, iv, macKey []byte, algs directionAlgorithms) (packetCipher, error) {
|
||||
stream, err := createFunc(key, iv)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
stream.XORKeyStream(streamDump[:dumpThisTime], streamDump[:dumpThisTime])
|
||||
remainingToDump -= dumpThisTime
|
||||
}
|
||||
|
||||
return stream, nil
|
||||
var streamDump []byte
|
||||
if skip > 0 {
|
||||
streamDump = make([]byte, 512)
|
||||
}
|
||||
|
||||
for remainingToDump := skip; remainingToDump > 0; {
|
||||
dumpThisTime := remainingToDump
|
||||
if dumpThisTime > len(streamDump) {
|
||||
dumpThisTime = len(streamDump)
|
||||
}
|
||||
stream.XORKeyStream(streamDump[:dumpThisTime], streamDump[:dumpThisTime])
|
||||
remainingToDump -= dumpThisTime
|
||||
}
|
||||
|
||||
mac := macModes[algs.MAC].new(macKey)
|
||||
return &streamPacketCipher{
|
||||
mac: mac,
|
||||
etm: macModes[algs.MAC].etm,
|
||||
macResult: make([]byte, mac.Size()),
|
||||
cipher: stream,
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
||||
// cipherModes documents properties of supported ciphers. Ciphers not included
|
||||
// are not supported and will not be negotiated, even if explicitly requested in
|
||||
// ClientConfig.Crypto.Ciphers.
|
||||
var cipherModes = map[string]*streamCipherMode{
|
||||
var cipherModes = map[string]*cipherMode{
|
||||
// Ciphers from RFC4344, which introduced many CTR-based ciphers. Algorithms
|
||||
// are defined in the order specified in the RFC.
|
||||
"aes128-ctr": {16, aes.BlockSize, 0, newAESCTR},
|
||||
"aes192-ctr": {24, aes.BlockSize, 0, newAESCTR},
|
||||
"aes256-ctr": {32, aes.BlockSize, 0, newAESCTR},
|
||||
"aes128-ctr": {16, aes.BlockSize, streamCipherMode(0, newAESCTR)},
|
||||
"aes192-ctr": {24, aes.BlockSize, streamCipherMode(0, newAESCTR)},
|
||||
"aes256-ctr": {32, aes.BlockSize, streamCipherMode(0, newAESCTR)},
|
||||
|
||||
// Ciphers from RFC4345, which introduces security-improved arcfour ciphers.
|
||||
// They are defined in the order specified in the RFC.
|
||||
"arcfour128": {16, 0, 1536, newRC4},
|
||||
"arcfour256": {32, 0, 1536, newRC4},
|
||||
"arcfour128": {16, 0, streamCipherMode(1536, newRC4)},
|
||||
"arcfour256": {32, 0, streamCipherMode(1536, newRC4)},
|
||||
|
||||
// Cipher defined in RFC 4253, which describes SSH Transport Layer Protocol.
|
||||
// Note that this cipher is not safe, as stated in RFC 4253: "Arcfour (and
|
||||
// RC4) has problems with weak keys, and should be used with caution."
|
||||
// RFC4345 introduces improved versions of Arcfour.
|
||||
"arcfour": {16, 0, 0, newRC4},
|
||||
"arcfour": {16, 0, streamCipherMode(0, newRC4)},
|
||||
|
||||
// AES-GCM is not a stream cipher, so it is constructed with a
|
||||
// special case. If we add any more non-stream ciphers, we
|
||||
// should invest a cleaner way to do this.
|
||||
gcmCipherID: {16, 12, 0, nil},
|
||||
// AEAD ciphers
|
||||
gcmCipherID: {16, 12, newGCMCipher},
|
||||
chacha20Poly1305ID: {64, 0, newChaCha20Cipher},
|
||||
|
||||
// CBC mode is insecure and so is not included in the default config.
|
||||
// (See http://www.isg.rhul.ac.uk/~kp/SandPfinal.pdf). If absolutely
|
||||
// needed, it's possible to specify a custom Config to enable it.
|
||||
// You should expect that an active attacker can recover plaintext if
|
||||
// you do.
|
||||
aes128cbcID: {16, aes.BlockSize, 0, nil},
|
||||
aes128cbcID: {16, aes.BlockSize, newAESCBCCipher},
|
||||
|
||||
// 3des-cbc is insecure and is disabled by default.
|
||||
tripledescbcID: {24, des.BlockSize, 0, nil},
|
||||
// 3des-cbc is insecure and is not included in the default
|
||||
// config.
|
||||
tripledescbcID: {24, des.BlockSize, newTripleDESCBCCipher},
|
||||
}
|
||||
|
||||
// prefixLen is the length of the packet prefix that contains the packet length
|
||||
|
@ -304,7 +307,7 @@ type gcmCipher struct {
|
|||
buf []byte
|
||||
}
|
||||
|
||||
func newGCMCipher(iv, key []byte) (packetCipher, error) {
|
||||
func newGCMCipher(key, iv, unusedMacKey []byte, unusedAlgs directionAlgorithms) (packetCipher, error) {
|
||||
c, err := aes.NewCipher(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -372,7 +375,7 @@ func (c *gcmCipher) readPacket(seqNum uint32, r io.Reader) ([]byte, error) {
|
|||
}
|
||||
length := binary.BigEndian.Uint32(c.prefix[:])
|
||||
if length > maxPacket {
|
||||
return nil, errors.New("ssh: max packet length exceeded.")
|
||||
return nil, errors.New("ssh: max packet length exceeded")
|
||||
}
|
||||
|
||||
if cap(c.buf) < int(length+gcmTagSize) {
|
||||
|
@ -422,7 +425,7 @@ type cbcCipher struct {
|
|||
oracleCamouflage uint32
|
||||
}
|
||||
|
||||
func newCBCCipher(c cipher.Block, iv, key, macKey []byte, algs directionAlgorithms) (packetCipher, error) {
|
||||
func newCBCCipher(c cipher.Block, key, iv, macKey []byte, algs directionAlgorithms) (packetCipher, error) {
|
||||
cbc := &cbcCipher{
|
||||
mac: macModes[algs.MAC].new(macKey),
|
||||
decrypter: cipher.NewCBCDecrypter(c, iv),
|
||||
|
@ -436,13 +439,13 @@ func newCBCCipher(c cipher.Block, iv, key, macKey []byte, algs directionAlgorith
|
|||
return cbc, nil
|
||||
}
|
||||
|
||||
func newAESCBCCipher(iv, key, macKey []byte, algs directionAlgorithms) (packetCipher, error) {
|
||||
func newAESCBCCipher(key, iv, macKey []byte, algs directionAlgorithms) (packetCipher, error) {
|
||||
c, err := aes.NewCipher(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cbc, err := newCBCCipher(c, iv, key, macKey, algs)
|
||||
cbc, err := newCBCCipher(c, key, iv, macKey, algs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -450,13 +453,13 @@ func newAESCBCCipher(iv, key, macKey []byte, algs directionAlgorithms) (packetCi
|
|||
return cbc, nil
|
||||
}
|
||||
|
||||
func newTripleDESCBCCipher(iv, key, macKey []byte, algs directionAlgorithms) (packetCipher, error) {
|
||||
func newTripleDESCBCCipher(key, iv, macKey []byte, algs directionAlgorithms) (packetCipher, error) {
|
||||
c, err := des.NewTripleDESCipher(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cbc, err := newCBCCipher(c, iv, key, macKey, algs)
|
||||
cbc, err := newCBCCipher(c, key, iv, macKey, algs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -548,11 +551,11 @@ func (c *cbcCipher) readPacketLeaky(seqNum uint32, r io.Reader) ([]byte, error)
|
|||
c.packetData = c.packetData[:entirePacketSize]
|
||||
}
|
||||
|
||||
if n, err := io.ReadFull(r, c.packetData[firstBlockLength:]); err != nil {
|
||||
n, err := io.ReadFull(r, c.packetData[firstBlockLength:])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
c.oracleCamouflage -= uint32(n)
|
||||
}
|
||||
c.oracleCamouflage -= uint32(n)
|
||||
|
||||
remainingCrypted := c.packetData[firstBlockLength:macStart]
|
||||
c.decrypter.CryptBlocks(remainingCrypted, remainingCrypted)
|
||||
|
@ -627,3 +630,142 @@ func (c *cbcCipher) writePacket(seqNum uint32, w io.Writer, rand io.Reader, pack
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
const chacha20Poly1305ID = "chacha20-poly1305@openssh.com"
|
||||
|
||||
// chacha20Poly1305Cipher implements the chacha20-poly1305@openssh.com
|
||||
// AEAD, which is described here:
|
||||
//
|
||||
// https://tools.ietf.org/html/draft-josefsson-ssh-chacha20-poly1305-openssh-00
|
||||
//
|
||||
// the methods here also implement padding, which RFC4253 Section 6
|
||||
// also requires of stream ciphers.
|
||||
type chacha20Poly1305Cipher struct {
|
||||
lengthKey [32]byte
|
||||
contentKey [32]byte
|
||||
buf []byte
|
||||
}
|
||||
|
||||
func newChaCha20Cipher(key, unusedIV, unusedMACKey []byte, unusedAlgs directionAlgorithms) (packetCipher, error) {
|
||||
if len(key) != 64 {
|
||||
panic(len(key))
|
||||
}
|
||||
|
||||
c := &chacha20Poly1305Cipher{
|
||||
buf: make([]byte, 256),
|
||||
}
|
||||
|
||||
copy(c.contentKey[:], key[:32])
|
||||
copy(c.lengthKey[:], key[32:])
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// The Poly1305 key is obtained by encrypting 32 0-bytes.
|
||||
var chacha20PolyKeyInput [32]byte
|
||||
|
||||
func (c *chacha20Poly1305Cipher) readPacket(seqNum uint32, r io.Reader) ([]byte, error) {
|
||||
var counter [16]byte
|
||||
binary.BigEndian.PutUint64(counter[8:], uint64(seqNum))
|
||||
|
||||
var polyKey [32]byte
|
||||
chacha20.XORKeyStream(polyKey[:], chacha20PolyKeyInput[:], &counter, &c.contentKey)
|
||||
|
||||
encryptedLength := c.buf[:4]
|
||||
if _, err := io.ReadFull(r, encryptedLength); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var lenBytes [4]byte
|
||||
chacha20.XORKeyStream(lenBytes[:], encryptedLength, &counter, &c.lengthKey)
|
||||
|
||||
length := binary.BigEndian.Uint32(lenBytes[:])
|
||||
if length > maxPacket {
|
||||
return nil, errors.New("ssh: invalid packet length, packet too large")
|
||||
}
|
||||
|
||||
contentEnd := 4 + length
|
||||
packetEnd := contentEnd + poly1305.TagSize
|
||||
if uint32(cap(c.buf)) < packetEnd {
|
||||
c.buf = make([]byte, packetEnd)
|
||||
copy(c.buf[:], encryptedLength)
|
||||
} else {
|
||||
c.buf = c.buf[:packetEnd]
|
||||
}
|
||||
|
||||
if _, err := io.ReadFull(r, c.buf[4:packetEnd]); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var mac [poly1305.TagSize]byte
|
||||
copy(mac[:], c.buf[contentEnd:packetEnd])
|
||||
if !poly1305.Verify(&mac, c.buf[:contentEnd], &polyKey) {
|
||||
return nil, errors.New("ssh: MAC failure")
|
||||
}
|
||||
|
||||
counter[0] = 1
|
||||
|
||||
plain := c.buf[4:contentEnd]
|
||||
chacha20.XORKeyStream(plain, plain, &counter, &c.contentKey)
|
||||
|
||||
padding := plain[0]
|
||||
if padding < 4 {
|
||||
// padding is a byte, so it automatically satisfies
|
||||
// the maximum size, which is 255.
|
||||
return nil, fmt.Errorf("ssh: illegal padding %d", padding)
|
||||
}
|
||||
|
||||
if int(padding)+1 >= len(plain) {
|
||||
return nil, fmt.Errorf("ssh: padding %d too large", padding)
|
||||
}
|
||||
|
||||
plain = plain[1 : len(plain)-int(padding)]
|
||||
|
||||
return plain, nil
|
||||
}
|
||||
|
||||
func (c *chacha20Poly1305Cipher) writePacket(seqNum uint32, w io.Writer, rand io.Reader, payload []byte) error {
|
||||
var counter [16]byte
|
||||
binary.BigEndian.PutUint64(counter[8:], uint64(seqNum))
|
||||
|
||||
var polyKey [32]byte
|
||||
chacha20.XORKeyStream(polyKey[:], chacha20PolyKeyInput[:], &counter, &c.contentKey)
|
||||
|
||||
// There is no blocksize, so fall back to multiple of 8 byte
|
||||
// padding, as described in RFC 4253, Sec 6.
|
||||
const packetSizeMultiple = 8
|
||||
|
||||
padding := packetSizeMultiple - (1+len(payload))%packetSizeMultiple
|
||||
if padding < 4 {
|
||||
padding += packetSizeMultiple
|
||||
}
|
||||
|
||||
// size (4 bytes), padding (1), payload, padding, tag.
|
||||
totalLength := 4 + 1 + len(payload) + padding + poly1305.TagSize
|
||||
if cap(c.buf) < totalLength {
|
||||
c.buf = make([]byte, totalLength)
|
||||
} else {
|
||||
c.buf = c.buf[:totalLength]
|
||||
}
|
||||
|
||||
binary.BigEndian.PutUint32(c.buf, uint32(1+len(payload)+padding))
|
||||
chacha20.XORKeyStream(c.buf, c.buf[:4], &counter, &c.lengthKey)
|
||||
c.buf[4] = byte(padding)
|
||||
copy(c.buf[5:], payload)
|
||||
packetEnd := 5 + len(payload) + padding
|
||||
if _, err := io.ReadFull(rand, c.buf[5+len(payload):packetEnd]); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
counter[0] = 1
|
||||
chacha20.XORKeyStream(c.buf[4:], c.buf[4:packetEnd], &counter, &c.contentKey)
|
||||
|
||||
var mac [poly1305.TagSize]byte
|
||||
poly1305.Sum(&mac, c.buf[:packetEnd], &polyKey)
|
||||
|
||||
copy(c.buf[packetEnd:], mac[:])
|
||||
|
||||
if _, err := w.Write(c.buf); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue