├── .gitignore ├── AUTHORS ├── LICENSE ├── Makefile ├── README.md ├── asserver └── launcher.go ├── idok.go ├── install-idok.sh ├── tunnel ├── config.go ├── doc.go ├── go.crypto │ ├── .hgignore │ ├── AUTHORS │ ├── CONTRIBUTORS │ ├── LICENSE │ ├── PATENTS │ ├── README │ ├── bcrypt │ │ ├── base64.go │ │ ├── bcrypt.go │ │ └── bcrypt_test.go │ ├── blowfish │ │ ├── block.go │ │ ├── blowfish_test.go │ │ ├── cipher.go │ │ └── const.go │ ├── bn256 │ │ ├── bn256.go │ │ ├── bn256_test.go │ │ ├── constants.go │ │ ├── curve.go │ │ ├── example_test.go │ │ ├── gfp12.go │ │ ├── gfp2.go │ │ ├── gfp6.go │ │ ├── optate.go │ │ └── twist.go │ ├── cast5 │ │ ├── cast5.go │ │ └── cast5_test.go │ ├── codereview.cfg │ ├── curve25519 │ │ ├── const_amd64.s │ │ ├── cswap_amd64.s │ │ ├── curve25519.go │ │ ├── curve25519_test.go │ │ ├── doc.go │ │ ├── freeze_amd64.s │ │ ├── ladderstep_amd64.s │ │ ├── mont25519_amd64.go │ │ ├── mul_amd64.s │ │ └── square_amd64.s │ ├── hkdf │ │ ├── example_test.go │ │ ├── hkdf.go │ │ └── hkdf_test.go │ ├── md4 │ │ ├── md4.go │ │ ├── md4_test.go │ │ └── md4block.go │ ├── nacl │ │ ├── box │ │ │ ├── box.go │ │ │ └── box_test.go │ │ └── secretbox │ │ │ ├── secretbox.go │ │ │ └── secretbox_test.go │ ├── ocsp │ │ ├── ocsp.go │ │ └── ocsp_test.go │ ├── openpgp │ │ ├── armor │ │ │ ├── armor.go │ │ │ ├── armor_test.go │ │ │ └── encode.go │ │ ├── canonical_text.go │ │ ├── canonical_text_test.go │ │ ├── clearsign │ │ │ ├── clearsign.go │ │ │ └── clearsign_test.go │ │ ├── elgamal │ │ │ ├── elgamal.go │ │ │ └── elgamal_test.go │ │ ├── errors │ │ │ └── errors.go │ │ ├── keys.go │ │ ├── keys_test.go │ │ ├── packet │ │ │ ├── compressed.go │ │ │ ├── compressed_test.go │ │ │ ├── config.go │ │ │ ├── encrypted_key.go │ │ │ ├── encrypted_key_test.go │ │ │ ├── literal.go │ │ │ ├── ocfb.go │ │ │ ├── ocfb_test.go │ │ │ ├── one_pass_signature.go │ │ │ ├── opaque.go │ │ │ ├── opaque_test.go │ │ │ ├── packet.go │ │ │ ├── packet_test.go │ │ │ ├── private_key.go │ │ │ ├── private_key_test.go │ │ │ ├── public_key.go │ │ │ ├── public_key_test.go │ │ │ ├── public_key_v3.go │ │ │ ├── public_key_v3_test.go │ │ │ ├── reader.go │ │ │ ├── signature.go │ │ │ ├── signature_test.go │ │ │ ├── signature_v3.go │ │ │ ├── signature_v3_test.go │ │ │ ├── symmetric_key_encrypted.go │ │ │ ├── symmetric_key_encrypted_test.go │ │ │ ├── symmetrically_encrypted.go │ │ │ ├── symmetrically_encrypted_test.go │ │ │ ├── userattribute.go │ │ │ ├── userattribute_test.go │ │ │ ├── userid.go │ │ │ └── userid_test.go │ │ ├── read.go │ │ ├── read_test.go │ │ ├── s2k │ │ │ ├── s2k.go │ │ │ └── s2k_test.go │ │ ├── write.go │ │ └── write_test.go │ ├── otr │ │ ├── libotr_test_helper.c │ │ ├── otr.go │ │ ├── otr_test.go │ │ └── smp.go │ ├── pbkdf2 │ │ ├── pbkdf2.go │ │ └── pbkdf2_test.go │ ├── poly1305 │ │ ├── const_amd64.s │ │ ├── poly1305.go │ │ ├── poly1305_amd64.s │ │ ├── poly1305_test.go │ │ ├── sum_amd64.go │ │ └── sum_ref.go │ ├── ripemd160 │ │ ├── ripemd160.go │ │ ├── ripemd160_test.go │ │ └── ripemd160block.go │ ├── salsa20 │ │ ├── salsa │ │ │ ├── hsalsa20.go │ │ │ ├── salsa2020_amd64.s │ │ │ ├── salsa208.go │ │ │ ├── salsa20_amd64.go │ │ │ ├── salsa20_ref.go │ │ │ └── salsa_test.go │ │ ├── salsa20.go │ │ └── salsa20_test.go │ ├── scrypt │ │ ├── scrypt.go │ │ └── scrypt_test.go │ ├── sha3 │ │ ├── doc.go │ │ ├── hashes.go │ │ ├── keccakKats.json.deflate │ │ ├── keccakf.go │ │ ├── register.go │ │ ├── sha3.go │ │ ├── sha3_test.go │ │ └── shake.go │ ├── ssh │ │ ├── agent │ │ │ ├── client.go │ │ │ ├── client_test.go │ │ │ ├── forward.go │ │ │ ├── keyring.go │ │ │ ├── server.go │ │ │ ├── server_test.go │ │ │ └── testdata_test.go │ │ ├── benchmark_test.go │ │ ├── buffer.go │ │ ├── buffer_test.go │ │ ├── certs.go │ │ ├── certs_test.go │ │ ├── channel.go │ │ ├── cipher.go │ │ ├── cipher_test.go │ │ ├── client.go │ │ ├── client.go.friend │ │ ├── client_auth.go │ │ ├── client_auth_test.go │ │ ├── client_test.go │ │ ├── common.go │ │ ├── connection.go │ │ ├── doc.go │ │ ├── example_test.go │ │ ├── handshake.go │ │ ├── handshake_test.go │ │ ├── kex.go │ │ ├── kex_test.go │ │ ├── keys.go │ │ ├── keys_test.go │ │ ├── mac.go │ │ ├── mempipe_test.go │ │ ├── messages.go │ │ ├── messages_test.go │ │ ├── mux.go │ │ ├── mux_test.go │ │ ├── server.go │ │ ├── session.go │ │ ├── session_test.go │ │ ├── tcpip.go │ │ ├── tcpip_test.go │ │ ├── terminal │ │ │ ├── terminal.go │ │ │ ├── terminal_test.go │ │ │ ├── util.go │ │ │ ├── util_bsd.go │ │ │ ├── util_linux.go │ │ │ └── util_windows.go │ │ ├── test │ │ │ ├── agent_unix_test.go │ │ │ ├── cert_test.go │ │ │ ├── doc.go │ │ │ ├── forward_unix_test.go │ │ │ ├── session_test.go │ │ │ ├── tcpip_test.go │ │ │ ├── test_unix_test.go │ │ │ └── testdata_test.go │ │ ├── testdata │ │ │ ├── doc.go │ │ │ └── keys.go │ │ ├── testdata_test.go │ │ ├── transport.go │ │ └── transport_test.go │ ├── twofish │ │ ├── twofish.go │ │ └── twofish_test.go │ ├── xtea │ │ ├── block.go │ │ ├── cipher.go │ │ └── xtea_test.go │ └── xts │ │ ├── xts.go │ │ └── xts_test.go ├── launcher.go └── parser.go └── utils ├── config.go ├── const.go ├── doc.go ├── github.go ├── ip.go ├── parsers.go ├── sender.go ├── signals.go └── usage.go /.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | .hg 3 | .hg/* 4 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Main author: 2 | Patrice FERLET (aka metald, ) 3 | 4 | Contributors: 5 | Alberto Gasparin 6 | 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014-2015, Patrice FERLET (Metal3d) 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 5 | 6 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 7 | 8 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 9 | 10 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 11 | 12 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 13 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | VERSION=$(shell git describe --tags) 3 | OPTS=-ldflags '-X main.VERSION $(VERSION)' 4 | 5 | version: 6 | go run $(OPTS) idok.go -version 7 | 8 | all: _prepare linux32 linux64 darwin freebsd64 freebsd32 windows pack 9 | 10 | _prepare: clean 11 | mkdir dist 12 | 13 | darwin: 14 | GOOS=darwin go build $(OPTS) -o idok-darwin idok.go 15 | 16 | linux32: 17 | GOARCH=386 go build $(OPTS) -o idok-i686 idok.go 18 | strip idok-i686 19 | 20 | linux64: 21 | go build $(OPTS) -o idok-x86_64 idok.go 22 | strip idok-x86_64 23 | 24 | freebsd32: 25 | GOOS=freebsd GOARCH=386 go build $(OPTS) -o idok-freebsd32 idok.go 26 | 27 | freebsd64: 28 | GOOS=freebsd go build $(OPTS) -o idok-freebsd64 idok.go 29 | 30 | windows: 31 | GOOS=windows go build $(OPTS) idok.go 32 | 33 | pack: 34 | mv idok-* idok.exe dist 35 | cd dist && \ 36 | gzip idok-i686 && \ 37 | gzip idok-x86_64 && \ 38 | gzip idok-darwin && \ 39 | gzip idok-freebsd32 && \ 40 | gzip idok-freebsd64 && \ 41 | zip idok idok.exe && \ 42 | rm idok.exe 43 | 44 | clean: 45 | rm -rf dist 46 | 47 | deploy: 48 | scp -C idok*.zip idok*.gz root@metal3d.org:/var/www/dists/ 49 | -------------------------------------------------------------------------------- /asserver/launcher.go: -------------------------------------------------------------------------------- 1 | // This package gives method to send streams as an http server. 2 | package asserver 3 | 4 | import ( 5 | "fmt" 6 | "github.com/metal3d/idok/utils" 7 | "io" 8 | "log" 9 | "net" 10 | "net/http" 11 | "os" 12 | "path/filepath" 13 | ) 14 | 15 | // Open a port locally and tell to kodi to stream 16 | // from this port 17 | func HttpServe(file, dir string, port int) { 18 | 19 | localip, err := utils.GetLocalInterfaceIP() 20 | log.Println(localip) 21 | if err != nil { 22 | log.Fatal(err) 23 | } 24 | 25 | // handle file http response 26 | fullpath := filepath.Join(dir, file) 27 | http.Handle("/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 28 | http.ServeFile(w, r, fullpath) 29 | })) 30 | 31 | // send xbmc the file query 32 | go utils.Send("http", localip, file, port) 33 | 34 | log.Fatal(http.ListenAndServe(fmt.Sprintf("0.0.0.0:%d", port), nil)); 35 | } 36 | 37 | // Serve STDIN stream from a local port 38 | func TCPServeStdin(port int) { 39 | 40 | localip, err := utils.GetLocalInterfaceIP() 41 | log.Println(localip) 42 | if err != nil { 43 | log.Fatal(err) 44 | } 45 | 46 | // send xbmc the file query 47 | go utils.Send("tcp", localip, "", port) 48 | con, err := net.Listen("tcp", fmt.Sprintf("0.0.0.0:%d", port)) 49 | if err != nil { 50 | log.Fatal(err) 51 | } 52 | c, err := con.Accept() 53 | if err != nil { 54 | log.Fatal(err) 55 | } 56 | go io.Copy(c, os.Stdin) 57 | 58 | } 59 | -------------------------------------------------------------------------------- /install-idok.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "This will install idok on your computer." 4 | echo "Select installation type" 5 | 6 | DIR="~/.local/bin" 7 | PREFIXCMD="bash -c" 8 | select choice in \ 9 | "Install for the current user $USER" \ 10 | "Install for all user in /usr/local/bin (will use sudo)" \ 11 | "Cancel" 12 | do 13 | case $REPLY in 14 | 1) DIR=~/.local/bin 15 | PREFIXCMD="bash -c" 16 | break 17 | ;; 18 | 2) DIR="/usr/local/bin" 19 | PREFIXCMD="sudo bash -c " 20 | break 21 | ;; 22 | 3) echo "Install cancelled, bye"; exit 0 23 | ;; 24 | *) echo "Not valid answer" 25 | ;; 26 | esac 27 | done 28 | 29 | ARCH=$(uname -i) 30 | 31 | [ $ARCH == "amd64" ] && ARCH="x86_64" 32 | [ $ARCH == "ia64" ] && ARCH="x86_64" 33 | [ $ARCH == "ia32" ] && ARCH="i686" 34 | [ $ARCH == "i386" ] && ARCH="i686" 35 | [ x"$OSTYPE" == x"darwin" ] && ARCH="darwin" 36 | [ x"$OSTYPE" == x"freebsd" ] && [ $ARCH == "i686" ] && ARCH="freebsd32" 37 | [ x"$OSTYPE" == x"freebsd" ] && [$ARCH == "x86_64" ] && ARCH="freebsd64" 38 | 39 | CMD="wget -q -O -" 40 | [ -x $(which curl) ] && CMD="curl -# -X GET -L" 41 | 42 | URL=$($CMD "https://api.github.com/repos/metal3d/idok/releases/latest" 2>/dev/null | awk -NF":" ' 43 | { 44 | if (/browser_download_url/ && /idok-'$ARCH'/){ 45 | print $2 ":" $3 46 | } 47 | } 48 | ') 49 | 50 | COMMAND="$CMD $URL | gunzip -c > $DIR/idok" 51 | bash -c "$PREFIXCMD \"$COMMAND\"" 52 | sleep 1 53 | bash -c "$PREFIXCMD \"chmod +x $DIR/idok\"" 54 | echo 55 | echo "Installation ok, idok installed in $DIR" 56 | exit 0 57 | -------------------------------------------------------------------------------- /tunnel/config.go: -------------------------------------------------------------------------------- 1 | package tunnel 2 | 3 | import ( 4 | "github.com/metal3d/idok/tunnel/go.crypto/ssh" 5 | "log" 6 | "os" 7 | "os/user" 8 | "path/filepath" 9 | ) 10 | 11 | // NewConfig returns a ssh.Config pointer with 3 auth method if possible, rsa key pair, 12 | // dsa keypair and user/pass 13 | func NewConfig(username, password string) *ssh.ClientConfig { 14 | u, _ := user.Current() 15 | home := u.HomeDir 16 | id_rsa_priv := filepath.Join(home, ".ssh", "id_rsa") 17 | id_dsa_priv := filepath.Join(home, ".ssh", "id_dsa") 18 | 19 | auth := []ssh.AuthMethod{} 20 | 21 | // Try to parse keypair 22 | if _, err := os.Stat(id_rsa_priv); err == nil { 23 | if keypair, err := parseSSHKeys(id_rsa_priv); err == nil { 24 | log.Println("Added RSA key") 25 | auth = append(auth, ssh.PublicKeys(keypair)) 26 | } 27 | } 28 | if _, err := os.Stat(id_dsa_priv); err == nil { 29 | if keypair, err := parseSSHKeys(id_dsa_priv); err == nil { 30 | log.Println("Added DSA key") 31 | auth = append(auth, ssh.PublicKeys(keypair)) 32 | } 33 | } 34 | 35 | // add password method 36 | auth = append(auth, ssh.Password(password)) 37 | 38 | // and set config 39 | return &ssh.ClientConfig{ 40 | User: username, 41 | Auth: auth, 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /tunnel/doc.go: -------------------------------------------------------------------------------- 1 | // Tunnel package contains methods to configure and stream through ssh tunnel. 2 | // 3 | // At this time, tunnel package needs to get patched version of 4 | // go.crypto/ssh because Dropbear ssh server has a little bug 5 | // on tunnelling protocol 6 | package tunnel 7 | -------------------------------------------------------------------------------- /tunnel/go.crypto/.hgignore: -------------------------------------------------------------------------------- 1 | # Add no patterns to .hgignore except for files generated by the build. 2 | syntax:glob 3 | last-change 4 | -------------------------------------------------------------------------------- /tunnel/go.crypto/AUTHORS: -------------------------------------------------------------------------------- 1 | # This source code refers to The Go Authors for copyright purposes. 2 | # The master list of authors is in the main Go distribution, 3 | # visible at http://tip.golang.org/AUTHORS. 4 | -------------------------------------------------------------------------------- /tunnel/go.crypto/CONTRIBUTORS: -------------------------------------------------------------------------------- 1 | # This source code was written by the Go contributors. 2 | # The master list of contributors is in the main Go distribution, 3 | # visible at http://tip.golang.org/CONTRIBUTORS. 4 | -------------------------------------------------------------------------------- /tunnel/go.crypto/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2009 The Go Authors. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above 10 | copyright notice, this list of conditions and the following disclaimer 11 | in the documentation and/or other materials provided with the 12 | distribution. 13 | * Neither the name of Google Inc. nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /tunnel/go.crypto/PATENTS: -------------------------------------------------------------------------------- 1 | Additional IP Rights Grant (Patents) 2 | 3 | "This implementation" means the copyrightable works distributed by 4 | Google as part of the Go project. 5 | 6 | Google hereby grants to You a perpetual, worldwide, non-exclusive, 7 | no-charge, royalty-free, irrevocable (except as stated in this section) 8 | patent license to make, have made, use, offer to sell, sell, import, 9 | transfer and otherwise run, modify and propagate the contents of this 10 | implementation of Go, where such license applies only to those patent 11 | claims, both currently owned or controlled by Google and acquired in 12 | the future, licensable by Google that are necessarily infringed by this 13 | implementation of Go. This grant does not include claims that would be 14 | infringed only as a consequence of further modification of this 15 | implementation. If you or your agent or exclusive licensee institute or 16 | order or agree to the institution of patent litigation against any 17 | entity (including a cross-claim or counterclaim in a lawsuit) alleging 18 | that this implementation of Go or any code incorporated within this 19 | implementation of Go constitutes direct or contributory patent 20 | infringement, or inducement of patent infringement, then any patent 21 | rights granted to you under this License for this implementation of Go 22 | shall terminate as of the date such litigation is filed. 23 | -------------------------------------------------------------------------------- /tunnel/go.crypto/README: -------------------------------------------------------------------------------- 1 | This repository holds supplementary Go cryptography libraries. 2 | 3 | To submit changes to this repository, see http://golang.org/doc/contribute.html. 4 | -------------------------------------------------------------------------------- /tunnel/go.crypto/bcrypt/base64.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package bcrypt 6 | 7 | import "encoding/base64" 8 | 9 | const alphabet = "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" 10 | 11 | var bcEncoding = base64.NewEncoding(alphabet) 12 | 13 | func base64Encode(src []byte) []byte { 14 | n := bcEncoding.EncodedLen(len(src)) 15 | dst := make([]byte, n) 16 | bcEncoding.Encode(dst, src) 17 | for dst[n-1] == '=' { 18 | n-- 19 | } 20 | return dst[:n] 21 | } 22 | 23 | func base64Decode(src []byte) ([]byte, error) { 24 | numOfEquals := 4 - (len(src) % 4) 25 | for i := 0; i < numOfEquals; i++ { 26 | src = append(src, '=') 27 | } 28 | 29 | dst := make([]byte, bcEncoding.DecodedLen(len(src))) 30 | n, err := bcEncoding.Decode(dst, src) 31 | if err != nil { 32 | return nil, err 33 | } 34 | return dst[:n], nil 35 | } 36 | -------------------------------------------------------------------------------- /tunnel/go.crypto/blowfish/cipher.go: -------------------------------------------------------------------------------- 1 | // Copyright 2010 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package blowfish implements Bruce Schneier's Blowfish encryption algorithm. 6 | package blowfish 7 | 8 | // The code is a port of Bruce Schneier's C implementation. 9 | // See http://www.schneier.com/blowfish.html. 10 | 11 | import "strconv" 12 | 13 | // The Blowfish block size in bytes. 14 | const BlockSize = 8 15 | 16 | // A Cipher is an instance of Blowfish encryption using a particular key. 17 | type Cipher struct { 18 | p [18]uint32 19 | s0, s1, s2, s3 [256]uint32 20 | } 21 | 22 | type KeySizeError int 23 | 24 | func (k KeySizeError) Error() string { 25 | return "crypto/blowfish: invalid key size " + strconv.Itoa(int(k)) 26 | } 27 | 28 | // NewCipher creates and returns a Cipher. 29 | // The key argument should be the Blowfish key, from 1 to 56 bytes. 30 | func NewCipher(key []byte) (*Cipher, error) { 31 | var result Cipher 32 | if k := len(key); k < 1 || k > 56 { 33 | return nil, KeySizeError(k) 34 | } 35 | initCipher(&result) 36 | ExpandKey(key, &result) 37 | return &result, nil 38 | } 39 | 40 | // NewSaltedCipher creates a returns a Cipher that folds a salt into its key 41 | // schedule. For most purposes, NewCipher, instead of NewSaltedCipher, is 42 | // sufficient and desirable. For bcrypt compatiblity, the key can be over 56 43 | // bytes. 44 | func NewSaltedCipher(key, salt []byte) (*Cipher, error) { 45 | if len(salt) == 0 { 46 | return NewCipher(key) 47 | } 48 | var result Cipher 49 | if k := len(key); k < 1 { 50 | return nil, KeySizeError(k) 51 | } 52 | initCipher(&result) 53 | expandKeyWithSalt(key, salt, &result) 54 | return &result, nil 55 | } 56 | 57 | // BlockSize returns the Blowfish block size, 8 bytes. 58 | // It is necessary to satisfy the Block interface in the 59 | // package "crypto/cipher". 60 | func (c *Cipher) BlockSize() int { return BlockSize } 61 | 62 | // Encrypt encrypts the 8-byte buffer src using the key k 63 | // and stores the result in dst. 64 | // Note that for amounts of data larger than a block, 65 | // it is not safe to just call Encrypt on successive blocks; 66 | // instead, use an encryption mode like CBC (see crypto/cipher/cbc.go). 67 | func (c *Cipher) Encrypt(dst, src []byte) { 68 | l := uint32(src[0])<<24 | uint32(src[1])<<16 | uint32(src[2])<<8 | uint32(src[3]) 69 | r := uint32(src[4])<<24 | uint32(src[5])<<16 | uint32(src[6])<<8 | uint32(src[7]) 70 | l, r = encryptBlock(l, r, c) 71 | dst[0], dst[1], dst[2], dst[3] = byte(l>>24), byte(l>>16), byte(l>>8), byte(l) 72 | dst[4], dst[5], dst[6], dst[7] = byte(r>>24), byte(r>>16), byte(r>>8), byte(r) 73 | } 74 | 75 | // Decrypt decrypts the 8-byte buffer src using the key k 76 | // and stores the result in dst. 77 | func (c *Cipher) Decrypt(dst, src []byte) { 78 | l := uint32(src[0])<<24 | uint32(src[1])<<16 | uint32(src[2])<<8 | uint32(src[3]) 79 | r := uint32(src[4])<<24 | uint32(src[5])<<16 | uint32(src[6])<<8 | uint32(src[7]) 80 | l, r = decryptBlock(l, r, c) 81 | dst[0], dst[1], dst[2], dst[3] = byte(l>>24), byte(l>>16), byte(l>>8), byte(l) 82 | dst[4], dst[5], dst[6], dst[7] = byte(r>>24), byte(r>>16), byte(r>>8), byte(r) 83 | } 84 | 85 | func initCipher(c *Cipher) { 86 | copy(c.p[0:], p[0:]) 87 | copy(c.s0[0:], s0[0:]) 88 | copy(c.s1[0:], s1[0:]) 89 | copy(c.s2[0:], s2[0:]) 90 | copy(c.s3[0:], s3[0:]) 91 | } 92 | -------------------------------------------------------------------------------- /tunnel/go.crypto/bn256/constants.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package bn256 6 | 7 | import ( 8 | "math/big" 9 | ) 10 | 11 | func bigFromBase10(s string) *big.Int { 12 | n, _ := new(big.Int).SetString(s, 10) 13 | return n 14 | } 15 | 16 | // u is the BN parameter that determines the prime: 1868033³. 17 | var u = bigFromBase10("6518589491078791937") 18 | 19 | // p is a prime over which we form a basic field: 36u⁴+36u³+24u³+6u+1. 20 | var p = bigFromBase10("65000549695646603732796438742359905742825358107623003571877145026864184071783") 21 | 22 | // Order is the number of elements in both G₁ and G₂: 36u⁴+36u³+18u³+6u+1. 23 | var Order = bigFromBase10("65000549695646603732796438742359905742570406053903786389881062969044166799969") 24 | 25 | // xiToPMinus1Over6 is ξ^((p-1)/6) where ξ = i+3. 26 | var xiToPMinus1Over6 = &gfP2{bigFromBase10("8669379979083712429711189836753509758585994370025260553045152614783263110636"), bigFromBase10("19998038925833620163537568958541907098007303196759855091367510456613536016040")} 27 | 28 | // xiToPMinus1Over3 is ξ^((p-1)/3) where ξ = i+3. 29 | var xiToPMinus1Over3 = &gfP2{bigFromBase10("26098034838977895781559542626833399156321265654106457577426020397262786167059"), bigFromBase10("15931493369629630809226283458085260090334794394361662678240713231519278691715")} 30 | 31 | // xiToPMinus1Over2 is ξ^((p-1)/2) where ξ = i+3. 32 | var xiToPMinus1Over2 = &gfP2{bigFromBase10("50997318142241922852281555961173165965672272825141804376761836765206060036244"), bigFromBase10("38665955945962842195025998234511023902832543644254935982879660597356748036009")} 33 | 34 | // xiToPSquaredMinus1Over3 is ξ^((p²-1)/3) where ξ = i+3. 35 | var xiToPSquaredMinus1Over3 = bigFromBase10("65000549695646603727810655408050771481677621702948236658134783353303381437752") 36 | 37 | // xiTo2PSquaredMinus2Over3 is ξ^((2p²-2)/3) where ξ = i+3 (a cubic root of unity, mod p). 38 | var xiTo2PSquaredMinus2Over3 = bigFromBase10("4985783334309134261147736404674766913742361673560802634030") 39 | 40 | // xiToPSquaredMinus1Over6 is ξ^((1p²-1)/6) where ξ = i+3 (a cubic root of -1, mod p). 41 | var xiToPSquaredMinus1Over6 = bigFromBase10("65000549695646603727810655408050771481677621702948236658134783353303381437753") 42 | 43 | // xiTo2PMinus2Over3 is ξ^((2p-2)/3) where ξ = i+3. 44 | var xiTo2PMinus2Over3 = &gfP2{bigFromBase10("19885131339612776214803633203834694332692106372356013117629940868870585019582"), bigFromBase10("21645619881471562101905880913352894726728173167203616652430647841922248593627")} 45 | -------------------------------------------------------------------------------- /tunnel/go.crypto/bn256/example_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package bn256 6 | 7 | import ( 8 | "crypto/rand" 9 | ) 10 | 11 | func ExamplePair() { 12 | // This implements the tripartite Diffie-Hellman algorithm from "A One 13 | // Round Protocol for Tripartite Diffie-Hellman", A. Joux. 14 | // http://www.springerlink.com/content/cddc57yyva0hburb/fulltext.pdf 15 | 16 | // Each of three parties, a, b and c, generate a private value. 17 | a, _ := rand.Int(rand.Reader, Order) 18 | b, _ := rand.Int(rand.Reader, Order) 19 | c, _ := rand.Int(rand.Reader, Order) 20 | 21 | // Then each party calculates g₁ and g₂ times their private value. 22 | pa := new(G1).ScalarBaseMult(a) 23 | qa := new(G2).ScalarBaseMult(a) 24 | 25 | pb := new(G1).ScalarBaseMult(b) 26 | qb := new(G2).ScalarBaseMult(b) 27 | 28 | pc := new(G1).ScalarBaseMult(c) 29 | qc := new(G2).ScalarBaseMult(c) 30 | 31 | // Now each party exchanges its public values with the other two and 32 | // all parties can calculate the shared key. 33 | k1 := Pair(pb, qc) 34 | k1.ScalarMult(k1, a) 35 | 36 | k2 := Pair(pc, qa) 37 | k2.ScalarMult(k2, b) 38 | 39 | k3 := Pair(pa, qb) 40 | k3.ScalarMult(k3, c) 41 | 42 | // k1, k2 and k3 will all be equal. 43 | } 44 | -------------------------------------------------------------------------------- /tunnel/go.crypto/cast5/cast5_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2010 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package cast5 6 | 7 | import ( 8 | "bytes" 9 | "encoding/hex" 10 | "testing" 11 | ) 12 | 13 | // This test vector is taken from RFC 2144, App B.1. 14 | // Since the other two test vectors are for reduced-round variants, we can't 15 | // use them. 16 | var basicTests = []struct { 17 | key, plainText, cipherText string 18 | }{ 19 | { 20 | "0123456712345678234567893456789a", 21 | "0123456789abcdef", 22 | "238b4fe5847e44b2", 23 | }, 24 | } 25 | 26 | func TestBasic(t *testing.T) { 27 | for i, test := range basicTests { 28 | key, _ := hex.DecodeString(test.key) 29 | plainText, _ := hex.DecodeString(test.plainText) 30 | expected, _ := hex.DecodeString(test.cipherText) 31 | 32 | c, err := NewCipher(key) 33 | if err != nil { 34 | t.Errorf("#%d: failed to create Cipher: %s", i, err) 35 | continue 36 | } 37 | var cipherText [BlockSize]byte 38 | c.Encrypt(cipherText[:], plainText) 39 | if !bytes.Equal(cipherText[:], expected) { 40 | t.Errorf("#%d: got:%x want:%x", i, cipherText, expected) 41 | } 42 | 43 | var plainTextAgain [BlockSize]byte 44 | c.Decrypt(plainTextAgain[:], cipherText[:]) 45 | if !bytes.Equal(plainTextAgain[:], plainText) { 46 | t.Errorf("#%d: got:%x want:%x", i, plainTextAgain, plainText) 47 | } 48 | } 49 | } 50 | 51 | // TestFull performs the test specified in RFC 2144, App B.2. 52 | // However, due to the length of time taken, it's disabled here and a more 53 | // limited version is included, below. 54 | func TestFull(t *testing.T) { 55 | if testing.Short() { 56 | // This is too slow for normal testing 57 | return 58 | } 59 | 60 | a, b := iterate(1000000) 61 | 62 | const expectedA = "eea9d0a249fd3ba6b3436fb89d6dca92" 63 | const expectedB = "b2c95eb00c31ad7180ac05b8e83d696e" 64 | 65 | if hex.EncodeToString(a) != expectedA { 66 | t.Errorf("a: got:%x want:%s", a, expectedA) 67 | } 68 | if hex.EncodeToString(b) != expectedB { 69 | t.Errorf("b: got:%x want:%s", b, expectedB) 70 | } 71 | } 72 | 73 | func iterate(iterations int) ([]byte, []byte) { 74 | const initValueHex = "0123456712345678234567893456789a" 75 | 76 | initValue, _ := hex.DecodeString(initValueHex) 77 | 78 | var a, b [16]byte 79 | copy(a[:], initValue) 80 | copy(b[:], initValue) 81 | 82 | for i := 0; i < iterations; i++ { 83 | c, _ := NewCipher(b[:]) 84 | c.Encrypt(a[:8], a[:8]) 85 | c.Encrypt(a[8:], a[8:]) 86 | c, _ = NewCipher(a[:]) 87 | c.Encrypt(b[:8], b[:8]) 88 | c.Encrypt(b[8:], b[8:]) 89 | } 90 | 91 | return a[:], b[:] 92 | } 93 | 94 | func TestLimited(t *testing.T) { 95 | a, b := iterate(1000) 96 | 97 | const expectedA = "23f73b14b02a2ad7dfb9f2c35644798d" 98 | const expectedB = "e5bf37eff14c456a40b21ce369370a9f" 99 | 100 | if hex.EncodeToString(a) != expectedA { 101 | t.Errorf("a: got:%x want:%s", a, expectedA) 102 | } 103 | if hex.EncodeToString(b) != expectedB { 104 | t.Errorf("b: got:%x want:%s", b, expectedB) 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /tunnel/go.crypto/codereview.cfg: -------------------------------------------------------------------------------- 1 | defaultcc: golang-codereviews@googlegroups.com 2 | contributors: http://go.googlecode.com/hg/CONTRIBUTORS 3 | -------------------------------------------------------------------------------- /tunnel/go.crypto/curve25519/const_amd64.s: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // This code was translated into a form compatible with 6a from the public 6 | // domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html 7 | 8 | // +build amd64,!gccgo 9 | 10 | DATA ·REDMASK51(SB)/8, $0x0007FFFFFFFFFFFF 11 | GLOBL ·REDMASK51(SB), $8 12 | 13 | DATA ·_121666_213(SB)/8, $996687872 14 | GLOBL ·_121666_213(SB), $8 15 | 16 | DATA ·_2P0(SB)/8, $0xFFFFFFFFFFFDA 17 | GLOBL ·_2P0(SB), $8 18 | 19 | DATA ·_2P1234(SB)/8, $0xFFFFFFFFFFFFE 20 | GLOBL ·_2P1234(SB), $8 21 | -------------------------------------------------------------------------------- /tunnel/go.crypto/curve25519/cswap_amd64.s: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // This code was translated into a form compatible with 6a from the public 6 | // domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html 7 | 8 | // +build amd64,!gccgo 9 | 10 | // func cswap(inout *[5]uint64, v uint64) 11 | TEXT ·cswap(SB),7,$0 12 | MOVQ inout+0(FP),DI 13 | MOVQ v+8(FP),SI 14 | 15 | CMPQ SI,$1 16 | MOVQ 0(DI),SI 17 | MOVQ 80(DI),DX 18 | MOVQ 8(DI),CX 19 | MOVQ 88(DI),R8 20 | MOVQ SI,R9 21 | CMOVQEQ DX,SI 22 | CMOVQEQ R9,DX 23 | MOVQ CX,R9 24 | CMOVQEQ R8,CX 25 | CMOVQEQ R9,R8 26 | MOVQ SI,0(DI) 27 | MOVQ DX,80(DI) 28 | MOVQ CX,8(DI) 29 | MOVQ R8,88(DI) 30 | MOVQ 16(DI),SI 31 | MOVQ 96(DI),DX 32 | MOVQ 24(DI),CX 33 | MOVQ 104(DI),R8 34 | MOVQ SI,R9 35 | CMOVQEQ DX,SI 36 | CMOVQEQ R9,DX 37 | MOVQ CX,R9 38 | CMOVQEQ R8,CX 39 | CMOVQEQ R9,R8 40 | MOVQ SI,16(DI) 41 | MOVQ DX,96(DI) 42 | MOVQ CX,24(DI) 43 | MOVQ R8,104(DI) 44 | MOVQ 32(DI),SI 45 | MOVQ 112(DI),DX 46 | MOVQ 40(DI),CX 47 | MOVQ 120(DI),R8 48 | MOVQ SI,R9 49 | CMOVQEQ DX,SI 50 | CMOVQEQ R9,DX 51 | MOVQ CX,R9 52 | CMOVQEQ R8,CX 53 | CMOVQEQ R9,R8 54 | MOVQ SI,32(DI) 55 | MOVQ DX,112(DI) 56 | MOVQ CX,40(DI) 57 | MOVQ R8,120(DI) 58 | MOVQ 48(DI),SI 59 | MOVQ 128(DI),DX 60 | MOVQ 56(DI),CX 61 | MOVQ 136(DI),R8 62 | MOVQ SI,R9 63 | CMOVQEQ DX,SI 64 | CMOVQEQ R9,DX 65 | MOVQ CX,R9 66 | CMOVQEQ R8,CX 67 | CMOVQEQ R9,R8 68 | MOVQ SI,48(DI) 69 | MOVQ DX,128(DI) 70 | MOVQ CX,56(DI) 71 | MOVQ R8,136(DI) 72 | MOVQ 64(DI),SI 73 | MOVQ 144(DI),DX 74 | MOVQ 72(DI),CX 75 | MOVQ 152(DI),R8 76 | MOVQ SI,R9 77 | CMOVQEQ DX,SI 78 | CMOVQEQ R9,DX 79 | MOVQ CX,R9 80 | CMOVQEQ R8,CX 81 | CMOVQEQ R9,R8 82 | MOVQ SI,64(DI) 83 | MOVQ DX,144(DI) 84 | MOVQ CX,72(DI) 85 | MOVQ R8,152(DI) 86 | MOVQ DI,AX 87 | MOVQ SI,DX 88 | RET 89 | -------------------------------------------------------------------------------- /tunnel/go.crypto/curve25519/curve25519_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package curve25519 6 | 7 | import ( 8 | "fmt" 9 | "testing" 10 | ) 11 | 12 | const expectedHex = "89161fde887b2b53de549af483940106ecc114d6982daa98256de23bdf77661a" 13 | 14 | func TestBaseScalarMult(t *testing.T) { 15 | var a, b [32]byte 16 | in := &a 17 | out := &b 18 | a[0] = 1 19 | 20 | for i := 0; i < 200; i++ { 21 | ScalarBaseMult(out, in) 22 | in, out = out, in 23 | } 24 | 25 | result := fmt.Sprintf("%x", in[:]) 26 | if result != expectedHex { 27 | t.Errorf("incorrect result: got %s, want %s", result, expectedHex) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /tunnel/go.crypto/curve25519/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package curve25519 provides an implementation of scalar multiplication on 6 | // the elliptic curve known as curve25519. See http://cr.yp.to/ecdh.html 7 | package curve25519 8 | 9 | // basePoint is the x coordinate of the generator of the curve. 10 | var basePoint = [32]byte{9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} 11 | 12 | // ScalarMult sets dst to the product in*base where dst and base are the x 13 | // coordinates of group points and all values are in little-endian form. 14 | func ScalarMult(dst, in, base *[32]byte) { 15 | scalarMult(dst, in, base) 16 | } 17 | 18 | // ScalarBaseMult sets dst to the product in*base where dst and base are the x 19 | // coordinates of group points, base is the standard generator and all values 20 | // are in little-endian form. 21 | func ScalarBaseMult(dst, in *[32]byte) { 22 | ScalarMult(dst, in, &basePoint) 23 | } 24 | -------------------------------------------------------------------------------- /tunnel/go.crypto/curve25519/freeze_amd64.s: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // This code was translated into a form compatible with 6a from the public 6 | // domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html 7 | 8 | // +build amd64,!gccgo 9 | 10 | // func freeze(inout *[5]uint64) 11 | TEXT ·freeze(SB),7,$96-8 12 | MOVQ inout+0(FP), DI 13 | 14 | MOVQ SP,R11 15 | MOVQ $31,CX 16 | NOTQ CX 17 | ANDQ CX,SP 18 | ADDQ $32,SP 19 | 20 | MOVQ R11,0(SP) 21 | MOVQ R12,8(SP) 22 | MOVQ R13,16(SP) 23 | MOVQ R14,24(SP) 24 | MOVQ R15,32(SP) 25 | MOVQ BX,40(SP) 26 | MOVQ BP,48(SP) 27 | MOVQ 0(DI),SI 28 | MOVQ 8(DI),DX 29 | MOVQ 16(DI),CX 30 | MOVQ 24(DI),R8 31 | MOVQ 32(DI),R9 32 | MOVQ ·REDMASK51(SB),AX 33 | MOVQ AX,R10 34 | SUBQ $18,R10 35 | MOVQ $3,R11 36 | REDUCELOOP: 37 | MOVQ SI,R12 38 | SHRQ $51,R12 39 | ANDQ AX,SI 40 | ADDQ R12,DX 41 | MOVQ DX,R12 42 | SHRQ $51,R12 43 | ANDQ AX,DX 44 | ADDQ R12,CX 45 | MOVQ CX,R12 46 | SHRQ $51,R12 47 | ANDQ AX,CX 48 | ADDQ R12,R8 49 | MOVQ R8,R12 50 | SHRQ $51,R12 51 | ANDQ AX,R8 52 | ADDQ R12,R9 53 | MOVQ R9,R12 54 | SHRQ $51,R12 55 | ANDQ AX,R9 56 | IMUL3Q $19,R12,R12 57 | ADDQ R12,SI 58 | SUBQ $1,R11 59 | JA REDUCELOOP 60 | MOVQ $1,R12 61 | CMPQ R10,SI 62 | CMOVQLT R11,R12 63 | CMPQ AX,DX 64 | CMOVQNE R11,R12 65 | CMPQ AX,CX 66 | CMOVQNE R11,R12 67 | CMPQ AX,R8 68 | CMOVQNE R11,R12 69 | CMPQ AX,R9 70 | CMOVQNE R11,R12 71 | NEGQ R12 72 | ANDQ R12,AX 73 | ANDQ R12,R10 74 | SUBQ R10,SI 75 | SUBQ AX,DX 76 | SUBQ AX,CX 77 | SUBQ AX,R8 78 | SUBQ AX,R9 79 | MOVQ SI,0(DI) 80 | MOVQ DX,8(DI) 81 | MOVQ CX,16(DI) 82 | MOVQ R8,24(DI) 83 | MOVQ R9,32(DI) 84 | MOVQ 0(SP),R11 85 | MOVQ 8(SP),R12 86 | MOVQ 16(SP),R13 87 | MOVQ 24(SP),R14 88 | MOVQ 32(SP),R15 89 | MOVQ 40(SP),BX 90 | MOVQ 48(SP),BP 91 | MOVQ R11,SP 92 | MOVQ DI,AX 93 | MOVQ SI,DX 94 | RET 95 | -------------------------------------------------------------------------------- /tunnel/go.crypto/curve25519/mul_amd64.s: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // This code was translated into a form compatible with 6a from the public 6 | // domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html 7 | 8 | // +build amd64,!gccgo 9 | 10 | // func mul(dest, a, b *[5]uint64) 11 | TEXT ·mul(SB),0,$128-24 12 | MOVQ dest+0(FP), DI 13 | MOVQ a+8(FP), SI 14 | MOVQ b+16(FP), DX 15 | 16 | MOVQ SP,R11 17 | MOVQ $31,CX 18 | NOTQ CX 19 | ANDQ CX,SP 20 | ADDQ $32,SP 21 | 22 | MOVQ R11,0(SP) 23 | MOVQ R12,8(SP) 24 | MOVQ R13,16(SP) 25 | MOVQ R14,24(SP) 26 | MOVQ R15,32(SP) 27 | MOVQ BX,40(SP) 28 | MOVQ BP,48(SP) 29 | MOVQ DI,56(SP) 30 | MOVQ DX,CX 31 | MOVQ 24(SI),DX 32 | IMUL3Q $19,DX,AX 33 | MOVQ AX,64(SP) 34 | MULQ 16(CX) 35 | MOVQ AX,R8 36 | MOVQ DX,R9 37 | MOVQ 32(SI),DX 38 | IMUL3Q $19,DX,AX 39 | MOVQ AX,72(SP) 40 | MULQ 8(CX) 41 | ADDQ AX,R8 42 | ADCQ DX,R9 43 | MOVQ 0(SI),AX 44 | MULQ 0(CX) 45 | ADDQ AX,R8 46 | ADCQ DX,R9 47 | MOVQ 0(SI),AX 48 | MULQ 8(CX) 49 | MOVQ AX,R10 50 | MOVQ DX,R11 51 | MOVQ 0(SI),AX 52 | MULQ 16(CX) 53 | MOVQ AX,R12 54 | MOVQ DX,R13 55 | MOVQ 0(SI),AX 56 | MULQ 24(CX) 57 | MOVQ AX,R14 58 | MOVQ DX,R15 59 | MOVQ 0(SI),AX 60 | MULQ 32(CX) 61 | MOVQ AX,BX 62 | MOVQ DX,BP 63 | MOVQ 8(SI),AX 64 | MULQ 0(CX) 65 | ADDQ AX,R10 66 | ADCQ DX,R11 67 | MOVQ 8(SI),AX 68 | MULQ 8(CX) 69 | ADDQ AX,R12 70 | ADCQ DX,R13 71 | MOVQ 8(SI),AX 72 | MULQ 16(CX) 73 | ADDQ AX,R14 74 | ADCQ DX,R15 75 | MOVQ 8(SI),AX 76 | MULQ 24(CX) 77 | ADDQ AX,BX 78 | ADCQ DX,BP 79 | MOVQ 8(SI),DX 80 | IMUL3Q $19,DX,AX 81 | MULQ 32(CX) 82 | ADDQ AX,R8 83 | ADCQ DX,R9 84 | MOVQ 16(SI),AX 85 | MULQ 0(CX) 86 | ADDQ AX,R12 87 | ADCQ DX,R13 88 | MOVQ 16(SI),AX 89 | MULQ 8(CX) 90 | ADDQ AX,R14 91 | ADCQ DX,R15 92 | MOVQ 16(SI),AX 93 | MULQ 16(CX) 94 | ADDQ AX,BX 95 | ADCQ DX,BP 96 | MOVQ 16(SI),DX 97 | IMUL3Q $19,DX,AX 98 | MULQ 24(CX) 99 | ADDQ AX,R8 100 | ADCQ DX,R9 101 | MOVQ 16(SI),DX 102 | IMUL3Q $19,DX,AX 103 | MULQ 32(CX) 104 | ADDQ AX,R10 105 | ADCQ DX,R11 106 | MOVQ 24(SI),AX 107 | MULQ 0(CX) 108 | ADDQ AX,R14 109 | ADCQ DX,R15 110 | MOVQ 24(SI),AX 111 | MULQ 8(CX) 112 | ADDQ AX,BX 113 | ADCQ DX,BP 114 | MOVQ 64(SP),AX 115 | MULQ 24(CX) 116 | ADDQ AX,R10 117 | ADCQ DX,R11 118 | MOVQ 64(SP),AX 119 | MULQ 32(CX) 120 | ADDQ AX,R12 121 | ADCQ DX,R13 122 | MOVQ 32(SI),AX 123 | MULQ 0(CX) 124 | ADDQ AX,BX 125 | ADCQ DX,BP 126 | MOVQ 72(SP),AX 127 | MULQ 16(CX) 128 | ADDQ AX,R10 129 | ADCQ DX,R11 130 | MOVQ 72(SP),AX 131 | MULQ 24(CX) 132 | ADDQ AX,R12 133 | ADCQ DX,R13 134 | MOVQ 72(SP),AX 135 | MULQ 32(CX) 136 | ADDQ AX,R14 137 | ADCQ DX,R15 138 | MOVQ ·REDMASK51(SB),SI 139 | SHLQ $13,R9:R8 140 | ANDQ SI,R8 141 | SHLQ $13,R11:R10 142 | ANDQ SI,R10 143 | ADDQ R9,R10 144 | SHLQ $13,R13:R12 145 | ANDQ SI,R12 146 | ADDQ R11,R12 147 | SHLQ $13,R15:R14 148 | ANDQ SI,R14 149 | ADDQ R13,R14 150 | SHLQ $13,BP:BX 151 | ANDQ SI,BX 152 | ADDQ R15,BX 153 | IMUL3Q $19,BP,DX 154 | ADDQ DX,R8 155 | MOVQ R8,DX 156 | SHRQ $51,DX 157 | ADDQ R10,DX 158 | MOVQ DX,CX 159 | SHRQ $51,DX 160 | ANDQ SI,R8 161 | ADDQ R12,DX 162 | MOVQ DX,R9 163 | SHRQ $51,DX 164 | ANDQ SI,CX 165 | ADDQ R14,DX 166 | MOVQ DX,AX 167 | SHRQ $51,DX 168 | ANDQ SI,R9 169 | ADDQ BX,DX 170 | MOVQ DX,R10 171 | SHRQ $51,DX 172 | ANDQ SI,AX 173 | IMUL3Q $19,DX,DX 174 | ADDQ DX,R8 175 | ANDQ SI,R10 176 | MOVQ R8,0(DI) 177 | MOVQ CX,8(DI) 178 | MOVQ R9,16(DI) 179 | MOVQ AX,24(DI) 180 | MOVQ R10,32(DI) 181 | MOVQ 0(SP),R11 182 | MOVQ 8(SP),R12 183 | MOVQ 16(SP),R13 184 | MOVQ 24(SP),R14 185 | MOVQ 32(SP),R15 186 | MOVQ 40(SP),BX 187 | MOVQ 48(SP),BP 188 | MOVQ R11,SP 189 | MOVQ DI,AX 190 | MOVQ SI,DX 191 | RET 192 | -------------------------------------------------------------------------------- /tunnel/go.crypto/curve25519/square_amd64.s: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // This code was translated into a form compatible with 6a from the public 6 | // domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html 7 | 8 | // +build amd64,!gccgo 9 | 10 | // func square(out, in *[5]uint64) 11 | TEXT ·square(SB),7,$96-16 12 | MOVQ out+0(FP), DI 13 | MOVQ in+8(FP), SI 14 | 15 | MOVQ SP,R11 16 | MOVQ $31,CX 17 | NOTQ CX 18 | ANDQ CX,SP 19 | ADDQ $32, SP 20 | 21 | MOVQ R11,0(SP) 22 | MOVQ R12,8(SP) 23 | MOVQ R13,16(SP) 24 | MOVQ R14,24(SP) 25 | MOVQ R15,32(SP) 26 | MOVQ BX,40(SP) 27 | MOVQ BP,48(SP) 28 | MOVQ 0(SI),AX 29 | MULQ 0(SI) 30 | MOVQ AX,CX 31 | MOVQ DX,R8 32 | MOVQ 0(SI),AX 33 | SHLQ $1,AX 34 | MULQ 8(SI) 35 | MOVQ AX,R9 36 | MOVQ DX,R10 37 | MOVQ 0(SI),AX 38 | SHLQ $1,AX 39 | MULQ 16(SI) 40 | MOVQ AX,R11 41 | MOVQ DX,R12 42 | MOVQ 0(SI),AX 43 | SHLQ $1,AX 44 | MULQ 24(SI) 45 | MOVQ AX,R13 46 | MOVQ DX,R14 47 | MOVQ 0(SI),AX 48 | SHLQ $1,AX 49 | MULQ 32(SI) 50 | MOVQ AX,R15 51 | MOVQ DX,BX 52 | MOVQ 8(SI),AX 53 | MULQ 8(SI) 54 | ADDQ AX,R11 55 | ADCQ DX,R12 56 | MOVQ 8(SI),AX 57 | SHLQ $1,AX 58 | MULQ 16(SI) 59 | ADDQ AX,R13 60 | ADCQ DX,R14 61 | MOVQ 8(SI),AX 62 | SHLQ $1,AX 63 | MULQ 24(SI) 64 | ADDQ AX,R15 65 | ADCQ DX,BX 66 | MOVQ 8(SI),DX 67 | IMUL3Q $38,DX,AX 68 | MULQ 32(SI) 69 | ADDQ AX,CX 70 | ADCQ DX,R8 71 | MOVQ 16(SI),AX 72 | MULQ 16(SI) 73 | ADDQ AX,R15 74 | ADCQ DX,BX 75 | MOVQ 16(SI),DX 76 | IMUL3Q $38,DX,AX 77 | MULQ 24(SI) 78 | ADDQ AX,CX 79 | ADCQ DX,R8 80 | MOVQ 16(SI),DX 81 | IMUL3Q $38,DX,AX 82 | MULQ 32(SI) 83 | ADDQ AX,R9 84 | ADCQ DX,R10 85 | MOVQ 24(SI),DX 86 | IMUL3Q $19,DX,AX 87 | MULQ 24(SI) 88 | ADDQ AX,R9 89 | ADCQ DX,R10 90 | MOVQ 24(SI),DX 91 | IMUL3Q $38,DX,AX 92 | MULQ 32(SI) 93 | ADDQ AX,R11 94 | ADCQ DX,R12 95 | MOVQ 32(SI),DX 96 | IMUL3Q $19,DX,AX 97 | MULQ 32(SI) 98 | ADDQ AX,R13 99 | ADCQ DX,R14 100 | MOVQ ·REDMASK51(SB),SI 101 | SHLQ $13,R8:CX 102 | ANDQ SI,CX 103 | SHLQ $13,R10:R9 104 | ANDQ SI,R9 105 | ADDQ R8,R9 106 | SHLQ $13,R12:R11 107 | ANDQ SI,R11 108 | ADDQ R10,R11 109 | SHLQ $13,R14:R13 110 | ANDQ SI,R13 111 | ADDQ R12,R13 112 | SHLQ $13,BX:R15 113 | ANDQ SI,R15 114 | ADDQ R14,R15 115 | IMUL3Q $19,BX,DX 116 | ADDQ DX,CX 117 | MOVQ CX,DX 118 | SHRQ $51,DX 119 | ADDQ R9,DX 120 | ANDQ SI,CX 121 | MOVQ DX,R8 122 | SHRQ $51,DX 123 | ADDQ R11,DX 124 | ANDQ SI,R8 125 | MOVQ DX,R9 126 | SHRQ $51,DX 127 | ADDQ R13,DX 128 | ANDQ SI,R9 129 | MOVQ DX,AX 130 | SHRQ $51,DX 131 | ADDQ R15,DX 132 | ANDQ SI,AX 133 | MOVQ DX,R10 134 | SHRQ $51,DX 135 | IMUL3Q $19,DX,DX 136 | ADDQ DX,CX 137 | ANDQ SI,R10 138 | MOVQ CX,0(DI) 139 | MOVQ R8,8(DI) 140 | MOVQ R9,16(DI) 141 | MOVQ AX,24(DI) 142 | MOVQ R10,32(DI) 143 | MOVQ 0(SP),R11 144 | MOVQ 8(SP),R12 145 | MOVQ 16(SP),R13 146 | MOVQ 24(SP),R14 147 | MOVQ 32(SP),R15 148 | MOVQ 40(SP),BX 149 | MOVQ 48(SP),BP 150 | MOVQ R11,SP 151 | MOVQ DI,AX 152 | MOVQ SI,DX 153 | RET 154 | -------------------------------------------------------------------------------- /tunnel/go.crypto/hkdf/example_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package hkdf_test 6 | 7 | import ( 8 | "bytes" 9 | "golang.org/x/crypto/hkdf" 10 | "crypto/rand" 11 | "crypto/sha256" 12 | "fmt" 13 | "io" 14 | ) 15 | 16 | // Usage example that expands one master key into three other cryptographically 17 | // secure keys. 18 | func Example_usage() { 19 | // Underlying hash function to use 20 | hash := sha256.New 21 | 22 | // Cryptographically secure master key. 23 | master := []byte{0x00, 0x01, 0x02, 0x03} // i.e. NOT this. 24 | 25 | // Non secret salt, optional (can be nil) 26 | // Recommended: hash-length sized random 27 | salt := make([]byte, hash().Size()) 28 | n, err := io.ReadFull(rand.Reader, salt) 29 | if n != len(salt) || err != nil { 30 | fmt.Println("error:", err) 31 | return 32 | } 33 | 34 | // Non secret context specific info, optional (can be nil). 35 | // Note, independent from the master key. 36 | info := []byte{0x03, 0x14, 0x15, 0x92, 0x65} 37 | 38 | // Create the key derivation function 39 | hkdf := hkdf.New(hash, master, salt, info) 40 | 41 | // Generate the required keys 42 | keys := make([][]byte, 3) 43 | for i := 0; i < len(keys); i++ { 44 | keys[i] = make([]byte, 24) 45 | n, err := io.ReadFull(hkdf, keys[i]) 46 | if n != len(keys[i]) || err != nil { 47 | fmt.Println("error:", err) 48 | return 49 | } 50 | } 51 | 52 | // Keys should contain 192 bit random keys 53 | for i := 1; i <= len(keys); i++ { 54 | fmt.Printf("Key #%d: %v\n", i, !bytes.Equal(keys[i-1], make([]byte, 24))) 55 | } 56 | 57 | // Output: 58 | // Key #1: true 59 | // Key #2: true 60 | // Key #3: true 61 | } 62 | -------------------------------------------------------------------------------- /tunnel/go.crypto/hkdf/hkdf.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package hkdf implements the HMAC-based Extract-and-Expand Key Derivation 6 | // Function (HKDF) as defined in RFC 5869. 7 | // 8 | // HKDF is a cryptographic key derivation function (KDF) with the goal of 9 | // expanding limited input keying material into one or more cryptographically 10 | // strong secret keys. 11 | // 12 | // RFC 5869: https://tools.ietf.org/html/rfc5869 13 | package hkdf 14 | 15 | import ( 16 | "crypto/hmac" 17 | "errors" 18 | "hash" 19 | "io" 20 | ) 21 | 22 | type hkdf struct { 23 | expander hash.Hash 24 | size int 25 | 26 | info []byte 27 | counter byte 28 | 29 | prev []byte 30 | cache []byte 31 | } 32 | 33 | func (f *hkdf) Read(p []byte) (int, error) { 34 | // Check whether enough data can be generated 35 | need := len(p) 36 | remains := len(f.cache) + int(255-f.counter+1)*f.size 37 | if remains < need { 38 | return 0, errors.New("hkdf: entropy limit reached") 39 | } 40 | // Read from the cache, if enough data is present 41 | n := copy(p, f.cache) 42 | p = p[n:] 43 | 44 | // Fill the buffer 45 | for len(p) > 0 { 46 | f.expander.Reset() 47 | f.expander.Write(f.prev) 48 | f.expander.Write(f.info) 49 | f.expander.Write([]byte{f.counter}) 50 | f.prev = f.expander.Sum(f.prev[:0]) 51 | f.counter++ 52 | 53 | // Copy the new batch into p 54 | f.cache = f.prev 55 | n = copy(p, f.cache) 56 | p = p[n:] 57 | } 58 | // Save leftovers for next run 59 | f.cache = f.cache[n:] 60 | 61 | return need, nil 62 | } 63 | 64 | // New returns a new HKDF using the given hash, the secret keying material to expand 65 | // and optional salt and info fields. 66 | func New(hash func() hash.Hash, secret, salt, info []byte) io.Reader { 67 | if salt == nil { 68 | salt = make([]byte, hash().Size()) 69 | } 70 | extractor := hmac.New(hash, salt) 71 | extractor.Write(secret) 72 | prk := extractor.Sum(nil) 73 | 74 | return &hkdf{hmac.New(hash, prk), extractor.Size(), info, 1, nil, nil} 75 | } 76 | -------------------------------------------------------------------------------- /tunnel/go.crypto/md4/md4.go: -------------------------------------------------------------------------------- 1 | // Copyright 2009 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package md4 implements the MD4 hash algorithm as defined in RFC 1320. 6 | package md4 7 | 8 | import ( 9 | "crypto" 10 | "hash" 11 | ) 12 | 13 | func init() { 14 | crypto.RegisterHash(crypto.MD4, New) 15 | } 16 | 17 | // The size of an MD4 checksum in bytes. 18 | const Size = 16 19 | 20 | // The blocksize of MD4 in bytes. 21 | const BlockSize = 64 22 | 23 | const ( 24 | _Chunk = 64 25 | _Init0 = 0x67452301 26 | _Init1 = 0xEFCDAB89 27 | _Init2 = 0x98BADCFE 28 | _Init3 = 0x10325476 29 | ) 30 | 31 | // digest represents the partial evaluation of a checksum. 32 | type digest struct { 33 | s [4]uint32 34 | x [_Chunk]byte 35 | nx int 36 | len uint64 37 | } 38 | 39 | func (d *digest) Reset() { 40 | d.s[0] = _Init0 41 | d.s[1] = _Init1 42 | d.s[2] = _Init2 43 | d.s[3] = _Init3 44 | d.nx = 0 45 | d.len = 0 46 | } 47 | 48 | // New returns a new hash.Hash computing the MD4 checksum. 49 | func New() hash.Hash { 50 | d := new(digest) 51 | d.Reset() 52 | return d 53 | } 54 | 55 | func (d *digest) Size() int { return Size } 56 | 57 | func (d *digest) BlockSize() int { return BlockSize } 58 | 59 | func (d *digest) Write(p []byte) (nn int, err error) { 60 | nn = len(p) 61 | d.len += uint64(nn) 62 | if d.nx > 0 { 63 | n := len(p) 64 | if n > _Chunk-d.nx { 65 | n = _Chunk - d.nx 66 | } 67 | for i := 0; i < n; i++ { 68 | d.x[d.nx+i] = p[i] 69 | } 70 | d.nx += n 71 | if d.nx == _Chunk { 72 | _Block(d, d.x[0:]) 73 | d.nx = 0 74 | } 75 | p = p[n:] 76 | } 77 | n := _Block(d, p) 78 | p = p[n:] 79 | if len(p) > 0 { 80 | d.nx = copy(d.x[:], p) 81 | } 82 | return 83 | } 84 | 85 | func (d0 *digest) Sum(in []byte) []byte { 86 | // Make a copy of d0, so that caller can keep writing and summing. 87 | d := new(digest) 88 | *d = *d0 89 | 90 | // Padding. Add a 1 bit and 0 bits until 56 bytes mod 64. 91 | len := d.len 92 | var tmp [64]byte 93 | tmp[0] = 0x80 94 | if len%64 < 56 { 95 | d.Write(tmp[0 : 56-len%64]) 96 | } else { 97 | d.Write(tmp[0 : 64+56-len%64]) 98 | } 99 | 100 | // Length in bits. 101 | len <<= 3 102 | for i := uint(0); i < 8; i++ { 103 | tmp[i] = byte(len >> (8 * i)) 104 | } 105 | d.Write(tmp[0:8]) 106 | 107 | if d.nx != 0 { 108 | panic("d.nx != 0") 109 | } 110 | 111 | for _, s := range d.s { 112 | in = append(in, byte(s>>0)) 113 | in = append(in, byte(s>>8)) 114 | in = append(in, byte(s>>16)) 115 | in = append(in, byte(s>>24)) 116 | } 117 | return in 118 | } 119 | -------------------------------------------------------------------------------- /tunnel/go.crypto/md4/md4_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2009 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package md4 6 | 7 | import ( 8 | "fmt" 9 | "io" 10 | "testing" 11 | ) 12 | 13 | type md4Test struct { 14 | out string 15 | in string 16 | } 17 | 18 | var golden = []md4Test{ 19 | {"31d6cfe0d16ae931b73c59d7e0c089c0", ""}, 20 | {"bde52cb31de33e46245e05fbdbd6fb24", "a"}, 21 | {"ec388dd78999dfc7cf4632465693b6bf", "ab"}, 22 | {"a448017aaf21d8525fc10ae87aa6729d", "abc"}, 23 | {"41decd8f579255c5200f86a4bb3ba740", "abcd"}, 24 | {"9803f4a34e8eb14f96adba49064a0c41", "abcde"}, 25 | {"804e7f1c2586e50b49ac65db5b645131", "abcdef"}, 26 | {"752f4adfe53d1da0241b5bc216d098fc", "abcdefg"}, 27 | {"ad9daf8d49d81988590a6f0e745d15dd", "abcdefgh"}, 28 | {"1e4e28b05464316b56402b3815ed2dfd", "abcdefghi"}, 29 | {"dc959c6f5d6f9e04e4380777cc964b3d", "abcdefghij"}, 30 | {"1b5701e265778898ef7de5623bbe7cc0", "Discard medicine more than two years old."}, 31 | {"d7f087e090fe7ad4a01cb59dacc9a572", "He who has a shady past knows that nice guys finish last."}, 32 | {"a6f8fd6df617c72837592fc3570595c9", "I wouldn't marry him with a ten foot pole."}, 33 | {"c92a84a9526da8abc240c05d6b1a1ce0", "Free! Free!/A trip/to Mars/for 900/empty jars/Burma Shave"}, 34 | {"f6013160c4dcb00847069fee3bb09803", "The days of the digital watch are numbered. -Tom Stoppard"}, 35 | {"2c3bb64f50b9107ed57640fe94bec09f", "Nepal premier won't resign."}, 36 | {"45b7d8a32c7806f2f7f897332774d6e4", "For every action there is an equal and opposite government program."}, 37 | {"b5b4f9026b175c62d7654bdc3a1cd438", "His money is twice tainted: 'taint yours and 'taint mine."}, 38 | {"caf44e80f2c20ce19b5ba1cab766e7bd", "There is no reason for any individual to have a computer in their home. -Ken Olsen, 1977"}, 39 | {"191fae6707f496aa54a6bce9f2ecf74d", "It's a tiny change to the code and not completely disgusting. - Bob Manchek"}, 40 | {"9ddc753e7a4ccee6081cd1b45b23a834", "size: a.out: bad magic"}, 41 | {"8d050f55b1cadb9323474564be08a521", "The major problem is with sendmail. -Mark Horton"}, 42 | {"ad6e2587f74c3e3cc19146f6127fa2e3", "Give me a rock, paper and scissors and I will move the world. CCFestoon"}, 43 | {"1d616d60a5fabe85589c3f1566ca7fca", "If the enemy is within range, then so are you."}, 44 | {"aec3326a4f496a2ced65a1963f84577f", "It's well we cannot hear the screams/That we create in others' dreams."}, 45 | {"77b4fd762d6b9245e61c50bf6ebf118b", "You remind me of a TV show, but that's all right: I watch it anyway."}, 46 | {"e8f48c726bae5e516f6ddb1a4fe62438", "C is as portable as Stonehedge!!"}, 47 | {"a3a84366e7219e887423b01f9be7166e", "Even if I could be Shakespeare, I think I should still choose to be Faraday. - A. Huxley"}, 48 | {"a6b7aa35157e984ef5d9b7f32e5fbb52", "The fugacity of a constituent in a mixture of gases at a given temperature is proportional to its mole fraction. Lewis-Randall Rule"}, 49 | {"75661f0545955f8f9abeeb17845f3fd6", "How can you write a big system without C++? -Paul Glick"}, 50 | } 51 | 52 | func TestGolden(t *testing.T) { 53 | for i := 0; i < len(golden); i++ { 54 | g := golden[i] 55 | c := New() 56 | for j := 0; j < 3; j++ { 57 | if j < 2 { 58 | io.WriteString(c, g.in) 59 | } else { 60 | io.WriteString(c, g.in[0:len(g.in)/2]) 61 | c.Sum(nil) 62 | io.WriteString(c, g.in[len(g.in)/2:]) 63 | } 64 | s := fmt.Sprintf("%x", c.Sum(nil)) 65 | if s != g.out { 66 | t.Fatalf("md4[%d](%s) = %s want %s", j, g.in, s, g.out) 67 | } 68 | c.Reset() 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /tunnel/go.crypto/md4/md4block.go: -------------------------------------------------------------------------------- 1 | // Copyright 2009 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // MD4 block step. 6 | // In its own file so that a faster assembly or C version 7 | // can be substituted easily. 8 | 9 | package md4 10 | 11 | var shift1 = []uint{3, 7, 11, 19} 12 | var shift2 = []uint{3, 5, 9, 13} 13 | var shift3 = []uint{3, 9, 11, 15} 14 | 15 | var xIndex2 = []uint{0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15} 16 | var xIndex3 = []uint{0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15} 17 | 18 | func _Block(dig *digest, p []byte) int { 19 | a := dig.s[0] 20 | b := dig.s[1] 21 | c := dig.s[2] 22 | d := dig.s[3] 23 | n := 0 24 | var X [16]uint32 25 | for len(p) >= _Chunk { 26 | aa, bb, cc, dd := a, b, c, d 27 | 28 | j := 0 29 | for i := 0; i < 16; i++ { 30 | X[i] = uint32(p[j]) | uint32(p[j+1])<<8 | uint32(p[j+2])<<16 | uint32(p[j+3])<<24 31 | j += 4 32 | } 33 | 34 | // If this needs to be made faster in the future, 35 | // the usual trick is to unroll each of these 36 | // loops by a factor of 4; that lets you replace 37 | // the shift[] lookups with constants and, 38 | // with suitable variable renaming in each 39 | // unrolled body, delete the a, b, c, d = d, a, b, c 40 | // (or you can let the optimizer do the renaming). 41 | // 42 | // The index variables are uint so that % by a power 43 | // of two can be optimized easily by a compiler. 44 | 45 | // Round 1. 46 | for i := uint(0); i < 16; i++ { 47 | x := i 48 | s := shift1[i%4] 49 | f := ((c ^ d) & b) ^ d 50 | a += f + X[x] 51 | a = a<>(32-s) 52 | a, b, c, d = d, a, b, c 53 | } 54 | 55 | // Round 2. 56 | for i := uint(0); i < 16; i++ { 57 | x := xIndex2[i] 58 | s := shift2[i%4] 59 | g := (b & c) | (b & d) | (c & d) 60 | a += g + X[x] + 0x5a827999 61 | a = a<>(32-s) 62 | a, b, c, d = d, a, b, c 63 | } 64 | 65 | // Round 3. 66 | for i := uint(0); i < 16; i++ { 67 | x := xIndex3[i] 68 | s := shift3[i%4] 69 | h := b ^ c ^ d 70 | a += h + X[x] + 0x6ed9eba1 71 | a = a<>(32-s) 72 | a, b, c, d = d, a, b, c 73 | } 74 | 75 | a += aa 76 | b += bb 77 | c += cc 78 | d += dd 79 | 80 | p = p[_Chunk:] 81 | n += _Chunk 82 | } 83 | 84 | dig.s[0] = a 85 | dig.s[1] = b 86 | dig.s[2] = c 87 | dig.s[3] = d 88 | return n 89 | } 90 | -------------------------------------------------------------------------------- /tunnel/go.crypto/nacl/box/box.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | /* 6 | Package box authenticates and encrypts messages using public-key cryptography. 7 | 8 | Box uses Curve25519, XSalsa20 and Poly1305 to encrypt and authenticate 9 | messages. The length of messages is not hidden. 10 | 11 | It is the caller's responsibility to ensure the uniqueness of nonces—for 12 | example, by using nonce 1 for the first message, nonce 2 for the second 13 | message, etc. Nonces are long enough that randomly generated nonces have 14 | negligible risk of collision. 15 | 16 | This package is interoperable with NaCl: http://nacl.cr.yp.to/box.html. 17 | */ 18 | package box 19 | 20 | import ( 21 | "golang.org/x/crypto/curve25519" 22 | "golang.org/x/crypto/nacl/secretbox" 23 | "golang.org/x/crypto/salsa20/salsa" 24 | "io" 25 | ) 26 | 27 | // Overhead is the number of bytes of overhead when boxing a message. 28 | const Overhead = secretbox.Overhead 29 | 30 | // GenerateKey generates a new public/private key pair suitable for use with 31 | // Seal and Open. 32 | func GenerateKey(rand io.Reader) (publicKey, privateKey *[32]byte, err error) { 33 | publicKey = new([32]byte) 34 | privateKey = new([32]byte) 35 | _, err = io.ReadFull(rand, privateKey[:]) 36 | if err != nil { 37 | publicKey = nil 38 | privateKey = nil 39 | return 40 | } 41 | 42 | curve25519.ScalarBaseMult(publicKey, privateKey) 43 | return 44 | } 45 | 46 | var zeros [16]byte 47 | 48 | // Precompute calculates the shared key between peersPublicKey and privateKey 49 | // and writes it to sharedKey. The shared key can be used with 50 | // OpenAfterPrecomputation and SealAfterPrecomputation to speed up processing 51 | // when using the same pair of keys repeatedly. 52 | func Precompute(sharedKey, peersPublicKey, privateKey *[32]byte) { 53 | curve25519.ScalarMult(sharedKey, privateKey, peersPublicKey) 54 | salsa.HSalsa20(sharedKey, &zeros, sharedKey, &salsa.Sigma) 55 | } 56 | 57 | // Seal appends an encrypted and authenticated copy of message to out, which 58 | // will be Overhead bytes longer than the original and must not overlap. The 59 | // nonce must be unique for each distinct message for a given pair of keys. 60 | func Seal(out, message []byte, nonce *[24]byte, peersPublicKey, privateKey *[32]byte) []byte { 61 | var sharedKey [32]byte 62 | Precompute(&sharedKey, peersPublicKey, privateKey) 63 | return secretbox.Seal(out, message, nonce, &sharedKey) 64 | } 65 | 66 | // SealAfterPrecomputation performs the same actions as Seal, but takes a 67 | // shared key as generated by Precompute. 68 | func SealAfterPrecomputation(out, message []byte, nonce *[24]byte, sharedKey *[32]byte) []byte { 69 | return secretbox.Seal(out, message, nonce, sharedKey) 70 | } 71 | 72 | // Open authenticates and decrypts a box produced by Seal and appends the 73 | // message to out, which must not overlap box. The output will be Overhead 74 | // bytes smaller than box. 75 | func Open(out, box []byte, nonce *[24]byte, peersPublicKey, privateKey *[32]byte) ([]byte, bool) { 76 | var sharedKey [32]byte 77 | Precompute(&sharedKey, peersPublicKey, privateKey) 78 | return secretbox.Open(out, box, nonce, &sharedKey) 79 | } 80 | 81 | // OpenAfterPrecomputation performs the same actions as Open, but takes a 82 | // shared key as generated by Precompute. 83 | func OpenAfterPrecomputation(out, box []byte, nonce *[24]byte, sharedKey *[32]byte) ([]byte, bool) { 84 | return secretbox.Open(out, box, nonce, sharedKey) 85 | } 86 | -------------------------------------------------------------------------------- /tunnel/go.crypto/nacl/box/box_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package box 6 | 7 | import ( 8 | "bytes" 9 | "crypto/rand" 10 | "encoding/hex" 11 | "testing" 12 | 13 | "golang.org/x/crypto/curve25519" 14 | ) 15 | 16 | func TestSealOpen(t *testing.T) { 17 | publicKey1, privateKey1, _ := GenerateKey(rand.Reader) 18 | publicKey2, privateKey2, _ := GenerateKey(rand.Reader) 19 | 20 | if *privateKey1 == *privateKey2 { 21 | t.Fatalf("private keys are equal!") 22 | } 23 | if *publicKey1 == *publicKey2 { 24 | t.Fatalf("public keys are equal!") 25 | } 26 | message := []byte("test message") 27 | var nonce [24]byte 28 | 29 | box := Seal(nil, message, &nonce, publicKey1, privateKey2) 30 | opened, ok := Open(nil, box, &nonce, publicKey2, privateKey1) 31 | if !ok { 32 | t.Fatalf("failed to open box") 33 | } 34 | 35 | if !bytes.Equal(opened, message) { 36 | t.Fatalf("got %x, want %x", opened, message) 37 | } 38 | 39 | for i := range box { 40 | box[i] ^= 0x40 41 | _, ok := Open(nil, box, &nonce, publicKey2, privateKey1) 42 | if ok { 43 | t.Fatalf("opened box with byte %d corrupted", i) 44 | } 45 | box[i] ^= 0x40 46 | } 47 | } 48 | 49 | func TestBox(t *testing.T) { 50 | var privateKey1, privateKey2 [32]byte 51 | for i := range privateKey1[:] { 52 | privateKey1[i] = 1 53 | } 54 | for i := range privateKey2[:] { 55 | privateKey2[i] = 2 56 | } 57 | 58 | var publicKey1 [32]byte 59 | curve25519.ScalarBaseMult(&publicKey1, &privateKey1) 60 | var message [64]byte 61 | for i := range message[:] { 62 | message[i] = 3 63 | } 64 | 65 | var nonce [24]byte 66 | for i := range nonce[:] { 67 | nonce[i] = 4 68 | } 69 | 70 | box := Seal(nil, message[:], &nonce, &publicKey1, &privateKey2) 71 | 72 | // expected was generated using the C implementation of NaCl. 73 | expected, _ := hex.DecodeString("78ea30b19d2341ebbdba54180f821eec265cf86312549bea8a37652a8bb94f07b78a73ed1708085e6ddd0e943bbdeb8755079a37eb31d86163ce241164a47629c0539f330b4914cd135b3855bc2a2dfc") 74 | 75 | if !bytes.Equal(box, expected) { 76 | t.Fatalf("box didn't match, got\n%x\n, expected\n%x", box, expected) 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /tunnel/go.crypto/nacl/secretbox/secretbox_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package secretbox 6 | 7 | import ( 8 | "bytes" 9 | "crypto/rand" 10 | "encoding/hex" 11 | "testing" 12 | ) 13 | 14 | func TestSealOpen(t *testing.T) { 15 | var key [32]byte 16 | var nonce [24]byte 17 | 18 | rand.Reader.Read(key[:]) 19 | rand.Reader.Read(nonce[:]) 20 | 21 | var box, opened []byte 22 | 23 | for msgLen := 0; msgLen < 128; msgLen += 17 { 24 | message := make([]byte, msgLen) 25 | rand.Reader.Read(message) 26 | 27 | box = Seal(box[:0], message, &nonce, &key) 28 | var ok bool 29 | opened, ok = Open(opened[:0], box, &nonce, &key) 30 | if !ok { 31 | t.Errorf("%d: failed to open box", msgLen) 32 | continue 33 | } 34 | 35 | if !bytes.Equal(opened, message) { 36 | t.Errorf("%d: got %x, expected %x", msgLen, opened, message) 37 | continue 38 | } 39 | } 40 | 41 | for i := range box { 42 | box[i] ^= 0x20 43 | _, ok := Open(opened[:0], box, &nonce, &key) 44 | if ok { 45 | t.Errorf("box was opened after corrupting byte %d", i) 46 | } 47 | box[i] ^= 0x20 48 | } 49 | } 50 | 51 | func TestSecretBox(t *testing.T) { 52 | var key [32]byte 53 | var nonce [24]byte 54 | var message [64]byte 55 | 56 | for i := range key[:] { 57 | key[i] = 1 58 | } 59 | for i := range nonce[:] { 60 | nonce[i] = 2 61 | } 62 | for i := range message[:] { 63 | message[i] = 3 64 | } 65 | 66 | box := Seal(nil, message[:], &nonce, &key) 67 | // expected was generated using the C implementation of NaCl. 68 | expected, _ := hex.DecodeString("8442bc313f4626f1359e3b50122b6ce6fe66ddfe7d39d14e637eb4fd5b45beadab55198df6ab5368439792a23c87db70acb6156dc5ef957ac04f6276cf6093b84be77ff0849cc33e34b7254d5a8f65ad") 69 | 70 | if !bytes.Equal(box, expected) { 71 | t.Fatalf("box didn't match, got\n%x\n, expected\n%x", box, expected) 72 | } 73 | } 74 | 75 | func TestAppend(t *testing.T) { 76 | var key [32]byte 77 | var nonce [24]byte 78 | var message [8]byte 79 | 80 | out := make([]byte, 4) 81 | box := Seal(out, message[:], &nonce, &key) 82 | if !bytes.Equal(box[:4], out[:4]) { 83 | t.Fatalf("Seal didn't correctly append") 84 | } 85 | 86 | out = make([]byte, 4, 100) 87 | box = Seal(out, message[:], &nonce, &key) 88 | if !bytes.Equal(box[:4], out[:4]) { 89 | t.Fatalf("Seal didn't correctly append with sufficient capacity.") 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /tunnel/go.crypto/openpgp/armor/armor_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2010 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package armor 6 | 7 | import ( 8 | "bytes" 9 | "hash/adler32" 10 | "io/ioutil" 11 | "testing" 12 | ) 13 | 14 | func TestDecodeEncode(t *testing.T) { 15 | buf := bytes.NewBuffer([]byte(armorExample1)) 16 | result, err := Decode(buf) 17 | if err != nil { 18 | t.Error(err) 19 | } 20 | expectedType := "PGP SIGNATURE" 21 | if result.Type != expectedType { 22 | t.Errorf("result.Type: got:%s want:%s", result.Type, expectedType) 23 | } 24 | if len(result.Header) != 1 { 25 | t.Errorf("len(result.Header): got:%d want:1", len(result.Header)) 26 | } 27 | v, ok := result.Header["Version"] 28 | if !ok || v != "GnuPG v1.4.10 (GNU/Linux)" { 29 | t.Errorf("result.Header: got:%#v", result.Header) 30 | } 31 | 32 | contents, err := ioutil.ReadAll(result.Body) 33 | if err != nil { 34 | t.Error(err) 35 | } 36 | 37 | if adler32.Checksum(contents) != 0x27b144be { 38 | t.Errorf("contents: got: %x", contents) 39 | } 40 | 41 | buf = bytes.NewBuffer(nil) 42 | w, err := Encode(buf, result.Type, result.Header) 43 | if err != nil { 44 | t.Error(err) 45 | } 46 | _, err = w.Write(contents) 47 | if err != nil { 48 | t.Error(err) 49 | } 50 | w.Close() 51 | 52 | if !bytes.Equal(buf.Bytes(), []byte(armorExample1)) { 53 | t.Errorf("got: %s\nwant: %s", string(buf.Bytes()), armorExample1) 54 | } 55 | } 56 | 57 | func TestLongHeader(t *testing.T) { 58 | buf := bytes.NewBuffer([]byte(armorLongLine)) 59 | result, err := Decode(buf) 60 | if err != nil { 61 | t.Error(err) 62 | return 63 | } 64 | value, ok := result.Header["Version"] 65 | if !ok { 66 | t.Errorf("missing Version header") 67 | } 68 | if value != longValueExpected { 69 | t.Errorf("got: %s want: %s", value, longValueExpected) 70 | } 71 | } 72 | 73 | const armorExample1 = `-----BEGIN PGP SIGNATURE----- 74 | Version: GnuPG v1.4.10 (GNU/Linux) 75 | 76 | iJwEAAECAAYFAk1Fv/0ACgkQo01+GMIMMbsYTwQAiAw+QAaNfY6WBdplZ/uMAccm 77 | 4g+81QPmTSGHnetSb6WBiY13kVzK4HQiZH8JSkmmroMLuGeJwsRTEL4wbjRyUKEt 78 | p1xwUZDECs234F1xiG5enc5SGlRtP7foLBz9lOsjx+LEcA4sTl5/2eZR9zyFZqWW 79 | TxRjs+fJCIFuo71xb1g= 80 | =/teI 81 | -----END PGP SIGNATURE-----` 82 | 83 | const armorLongLine = `-----BEGIN PGP SIGNATURE----- 84 | Version: 0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz 85 | 86 | iQEcBAABAgAGBQJMtFESAAoJEKsQXJGvOPsVj40H/1WW6jaMXv4BW+1ueDSMDwM8 87 | kx1fLOXbVM5/Kn5LStZNt1jWWnpxdz7eq3uiqeCQjmqUoRde3YbB2EMnnwRbAhpp 88 | cacnAvy9ZQ78OTxUdNW1mhX5bS6q1MTEJnl+DcyigD70HG/yNNQD7sOPMdYQw0TA 89 | byQBwmLwmTsuZsrYqB68QyLHI+DUugn+kX6Hd2WDB62DKa2suoIUIHQQCd/ofwB3 90 | WfCYInXQKKOSxu2YOg2Eb4kLNhSMc1i9uKUWAH+sdgJh7NBgdoE4MaNtBFkHXRvv 91 | okWuf3+xA9ksp1npSY/mDvgHijmjvtpRDe6iUeqfCn8N9u9CBg8geANgaG8+QA4= 92 | =wfQG 93 | -----END PGP SIGNATURE-----` 94 | 95 | const longValueExpected = "0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz" 96 | -------------------------------------------------------------------------------- /tunnel/go.crypto/openpgp/armor/encode.go: -------------------------------------------------------------------------------- 1 | // Copyright 2010 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package armor 6 | 7 | import ( 8 | "encoding/base64" 9 | "io" 10 | ) 11 | 12 | var armorHeaderSep = []byte(": ") 13 | var blockEnd = []byte("\n=") 14 | var newline = []byte("\n") 15 | var armorEndOfLineOut = []byte("-----\n") 16 | 17 | // writeSlices writes its arguments to the given Writer. 18 | func writeSlices(out io.Writer, slices ...[]byte) (err error) { 19 | for _, s := range slices { 20 | _, err = out.Write(s) 21 | if err != nil { 22 | return err 23 | } 24 | } 25 | return 26 | } 27 | 28 | // lineBreaker breaks data across several lines, all of the same byte length 29 | // (except possibly the last). Lines are broken with a single '\n'. 30 | type lineBreaker struct { 31 | lineLength int 32 | line []byte 33 | used int 34 | out io.Writer 35 | haveWritten bool 36 | } 37 | 38 | func newLineBreaker(out io.Writer, lineLength int) *lineBreaker { 39 | return &lineBreaker{ 40 | lineLength: lineLength, 41 | line: make([]byte, lineLength), 42 | used: 0, 43 | out: out, 44 | } 45 | } 46 | 47 | func (l *lineBreaker) Write(b []byte) (n int, err error) { 48 | n = len(b) 49 | 50 | if n == 0 { 51 | return 52 | } 53 | 54 | if l.used == 0 && l.haveWritten { 55 | _, err = l.out.Write([]byte{'\n'}) 56 | if err != nil { 57 | return 58 | } 59 | } 60 | 61 | if l.used+len(b) < l.lineLength { 62 | l.used += copy(l.line[l.used:], b) 63 | return 64 | } 65 | 66 | l.haveWritten = true 67 | _, err = l.out.Write(l.line[0:l.used]) 68 | if err != nil { 69 | return 70 | } 71 | excess := l.lineLength - l.used 72 | l.used = 0 73 | 74 | _, err = l.out.Write(b[0:excess]) 75 | if err != nil { 76 | return 77 | } 78 | 79 | _, err = l.Write(b[excess:]) 80 | return 81 | } 82 | 83 | func (l *lineBreaker) Close() (err error) { 84 | if l.used > 0 { 85 | _, err = l.out.Write(l.line[0:l.used]) 86 | if err != nil { 87 | return 88 | } 89 | } 90 | 91 | return 92 | } 93 | 94 | // encoding keeps track of a running CRC24 over the data which has been written 95 | // to it and outputs a OpenPGP checksum when closed, followed by an armor 96 | // trailer. 97 | // 98 | // It's built into a stack of io.Writers: 99 | // encoding -> base64 encoder -> lineBreaker -> out 100 | type encoding struct { 101 | out io.Writer 102 | breaker *lineBreaker 103 | b64 io.WriteCloser 104 | crc uint32 105 | blockType []byte 106 | } 107 | 108 | func (e *encoding) Write(data []byte) (n int, err error) { 109 | e.crc = crc24(e.crc, data) 110 | return e.b64.Write(data) 111 | } 112 | 113 | func (e *encoding) Close() (err error) { 114 | err = e.b64.Close() 115 | if err != nil { 116 | return 117 | } 118 | e.breaker.Close() 119 | 120 | var checksumBytes [3]byte 121 | checksumBytes[0] = byte(e.crc >> 16) 122 | checksumBytes[1] = byte(e.crc >> 8) 123 | checksumBytes[2] = byte(e.crc) 124 | 125 | var b64ChecksumBytes [4]byte 126 | base64.StdEncoding.Encode(b64ChecksumBytes[:], checksumBytes[:]) 127 | 128 | return writeSlices(e.out, blockEnd, b64ChecksumBytes[:], newline, armorEnd, e.blockType, armorEndOfLine) 129 | } 130 | 131 | // Encode returns a WriteCloser which will encode the data written to it in 132 | // OpenPGP armor. 133 | func Encode(out io.Writer, blockType string, headers map[string]string) (w io.WriteCloser, err error) { 134 | bType := []byte(blockType) 135 | err = writeSlices(out, armorStart, bType, armorEndOfLineOut) 136 | if err != nil { 137 | return 138 | } 139 | 140 | for k, v := range headers { 141 | err = writeSlices(out, []byte(k), armorHeaderSep, []byte(v), newline) 142 | if err != nil { 143 | return 144 | } 145 | } 146 | 147 | _, err = out.Write(newline) 148 | if err != nil { 149 | return 150 | } 151 | 152 | e := &encoding{ 153 | out: out, 154 | breaker: newLineBreaker(out, 64), 155 | crc: crc24Init, 156 | blockType: bType, 157 | } 158 | e.b64 = base64.NewEncoder(base64.StdEncoding, e.breaker) 159 | return e, nil 160 | } 161 | -------------------------------------------------------------------------------- /tunnel/go.crypto/openpgp/canonical_text.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package openpgp 6 | 7 | import "hash" 8 | 9 | // NewCanonicalTextHash reformats text written to it into the canonical 10 | // form and then applies the hash h. See RFC 4880, section 5.2.1. 11 | func NewCanonicalTextHash(h hash.Hash) hash.Hash { 12 | return &canonicalTextHash{h, 0} 13 | } 14 | 15 | type canonicalTextHash struct { 16 | h hash.Hash 17 | s int 18 | } 19 | 20 | var newline = []byte{'\r', '\n'} 21 | 22 | func (cth *canonicalTextHash) Write(buf []byte) (int, error) { 23 | start := 0 24 | 25 | for i, c := range buf { 26 | switch cth.s { 27 | case 0: 28 | if c == '\r' { 29 | cth.s = 1 30 | } else if c == '\n' { 31 | cth.h.Write(buf[start:i]) 32 | cth.h.Write(newline) 33 | start = i + 1 34 | } 35 | case 1: 36 | cth.s = 0 37 | } 38 | } 39 | 40 | cth.h.Write(buf[start:]) 41 | return len(buf), nil 42 | } 43 | 44 | func (cth *canonicalTextHash) Sum(in []byte) []byte { 45 | return cth.h.Sum(in) 46 | } 47 | 48 | func (cth *canonicalTextHash) Reset() { 49 | cth.h.Reset() 50 | cth.s = 0 51 | } 52 | 53 | func (cth *canonicalTextHash) Size() int { 54 | return cth.h.Size() 55 | } 56 | 57 | func (cth *canonicalTextHash) BlockSize() int { 58 | return cth.h.BlockSize() 59 | } 60 | -------------------------------------------------------------------------------- /tunnel/go.crypto/openpgp/canonical_text_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package openpgp 6 | 7 | import ( 8 | "bytes" 9 | "testing" 10 | ) 11 | 12 | type recordingHash struct { 13 | buf *bytes.Buffer 14 | } 15 | 16 | func (r recordingHash) Write(b []byte) (n int, err error) { 17 | return r.buf.Write(b) 18 | } 19 | 20 | func (r recordingHash) Sum(in []byte) []byte { 21 | return append(in, r.buf.Bytes()...) 22 | } 23 | 24 | func (r recordingHash) Reset() { 25 | panic("shouldn't be called") 26 | } 27 | 28 | func (r recordingHash) Size() int { 29 | panic("shouldn't be called") 30 | } 31 | 32 | func (r recordingHash) BlockSize() int { 33 | panic("shouldn't be called") 34 | } 35 | 36 | func testCanonicalText(t *testing.T, input, expected string) { 37 | r := recordingHash{bytes.NewBuffer(nil)} 38 | c := NewCanonicalTextHash(r) 39 | c.Write([]byte(input)) 40 | result := c.Sum(nil) 41 | if expected != string(result) { 42 | t.Errorf("input: %x got: %x want: %x", input, result, expected) 43 | } 44 | } 45 | 46 | func TestCanonicalText(t *testing.T) { 47 | testCanonicalText(t, "foo\n", "foo\r\n") 48 | testCanonicalText(t, "foo", "foo") 49 | testCanonicalText(t, "foo\r\n", "foo\r\n") 50 | testCanonicalText(t, "foo\r\nbar", "foo\r\nbar") 51 | testCanonicalText(t, "foo\r\nbar\n\n", "foo\r\nbar\r\n\r\n") 52 | } 53 | -------------------------------------------------------------------------------- /tunnel/go.crypto/openpgp/elgamal/elgamal.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package elgamal implements ElGamal encryption, suitable for OpenPGP, 6 | // as specified in "A Public-Key Cryptosystem and a Signature Scheme Based on 7 | // Discrete Logarithms," IEEE Transactions on Information Theory, v. IT-31, 8 | // n. 4, 1985, pp. 469-472. 9 | // 10 | // This form of ElGamal embeds PKCS#1 v1.5 padding, which may make it 11 | // unsuitable for other protocols. RSA should be used in preference in any 12 | // case. 13 | package elgamal 14 | 15 | import ( 16 | "crypto/rand" 17 | "crypto/subtle" 18 | "errors" 19 | "io" 20 | "math/big" 21 | ) 22 | 23 | // PublicKey represents an ElGamal public key. 24 | type PublicKey struct { 25 | G, P, Y *big.Int 26 | } 27 | 28 | // PrivateKey represents an ElGamal private key. 29 | type PrivateKey struct { 30 | PublicKey 31 | X *big.Int 32 | } 33 | 34 | // Encrypt encrypts the given message to the given public key. The result is a 35 | // pair of integers. Errors can result from reading random, or because msg is 36 | // too large to be encrypted to the public key. 37 | func Encrypt(random io.Reader, pub *PublicKey, msg []byte) (c1, c2 *big.Int, err error) { 38 | pLen := (pub.P.BitLen() + 7) / 8 39 | if len(msg) > pLen-11 { 40 | err = errors.New("elgamal: message too long") 41 | return 42 | } 43 | 44 | // EM = 0x02 || PS || 0x00 || M 45 | em := make([]byte, pLen-1) 46 | em[0] = 2 47 | ps, mm := em[1:len(em)-len(msg)-1], em[len(em)-len(msg):] 48 | err = nonZeroRandomBytes(ps, random) 49 | if err != nil { 50 | return 51 | } 52 | em[len(em)-len(msg)-1] = 0 53 | copy(mm, msg) 54 | 55 | m := new(big.Int).SetBytes(em) 56 | 57 | k, err := rand.Int(random, pub.P) 58 | if err != nil { 59 | return 60 | } 61 | 62 | c1 = new(big.Int).Exp(pub.G, k, pub.P) 63 | s := new(big.Int).Exp(pub.Y, k, pub.P) 64 | c2 = s.Mul(s, m) 65 | c2.Mod(c2, pub.P) 66 | 67 | return 68 | } 69 | 70 | // Decrypt takes two integers, resulting from an ElGamal encryption, and 71 | // returns the plaintext of the message. An error can result only if the 72 | // ciphertext is invalid. Users should keep in mind that this is a padding 73 | // oracle and thus, if exposed to an adaptive chosen ciphertext attack, can 74 | // be used to break the cryptosystem. See ``Chosen Ciphertext Attacks 75 | // Against Protocols Based on the RSA Encryption Standard PKCS #1'', Daniel 76 | // Bleichenbacher, Advances in Cryptology (Crypto '98), 77 | func Decrypt(priv *PrivateKey, c1, c2 *big.Int) (msg []byte, err error) { 78 | s := new(big.Int).Exp(c1, priv.X, priv.P) 79 | s.ModInverse(s, priv.P) 80 | s.Mul(s, c2) 81 | s.Mod(s, priv.P) 82 | em := s.Bytes() 83 | 84 | firstByteIsTwo := subtle.ConstantTimeByteEq(em[0], 2) 85 | 86 | // The remainder of the plaintext must be a string of non-zero random 87 | // octets, followed by a 0, followed by the message. 88 | // lookingForIndex: 1 iff we are still looking for the zero. 89 | // index: the offset of the first zero byte. 90 | var lookingForIndex, index int 91 | lookingForIndex = 1 92 | 93 | for i := 1; i < len(em); i++ { 94 | equals0 := subtle.ConstantTimeByteEq(em[i], 0) 95 | index = subtle.ConstantTimeSelect(lookingForIndex&equals0, i, index) 96 | lookingForIndex = subtle.ConstantTimeSelect(equals0, 0, lookingForIndex) 97 | } 98 | 99 | if firstByteIsTwo != 1 || lookingForIndex != 0 || index < 9 { 100 | return nil, errors.New("elgamal: decryption error") 101 | } 102 | return em[index+1:], nil 103 | } 104 | 105 | // nonZeroRandomBytes fills the given slice with non-zero random octets. 106 | func nonZeroRandomBytes(s []byte, rand io.Reader) (err error) { 107 | _, err = io.ReadFull(rand, s) 108 | if err != nil { 109 | return 110 | } 111 | 112 | for i := 0; i < len(s); i++ { 113 | for s[i] == 0 { 114 | _, err = io.ReadFull(rand, s[i:i+1]) 115 | if err != nil { 116 | return 117 | } 118 | } 119 | } 120 | 121 | return 122 | } 123 | -------------------------------------------------------------------------------- /tunnel/go.crypto/openpgp/elgamal/elgamal_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package elgamal 6 | 7 | import ( 8 | "bytes" 9 | "crypto/rand" 10 | "math/big" 11 | "testing" 12 | ) 13 | 14 | // This is the 1024-bit MODP group from RFC 5114, section 2.1: 15 | const primeHex = "B10B8F96A080E01DDE92DE5EAE5D54EC52C99FBCFB06A3C69A6A9DCA52D23B616073E28675A23D189838EF1E2EE652C013ECB4AEA906112324975C3CD49B83BFACCBDD7D90C4BD7098488E9C219A73724EFFD6FAE5644738FAA31A4FF55BCCC0A151AF5F0DC8B4BD45BF37DF365C1A65E68CFDA76D4DA708DF1FB2BC2E4A4371" 16 | 17 | const generatorHex = "A4D1CBD5C3FD34126765A442EFB99905F8104DD258AC507FD6406CFF14266D31266FEA1E5C41564B777E690F5504F213160217B4B01B886A5E91547F9E2749F4D7FBD7D3B9A92EE1909D0D2263F80A76A6A24C087A091F531DBF0A0169B6A28AD662A4D18E73AFA32D779D5918D08BC8858F4DCEF97C2A24855E6EEB22B3B2E5" 18 | 19 | func fromHex(hex string) *big.Int { 20 | n, ok := new(big.Int).SetString(hex, 16) 21 | if !ok { 22 | panic("failed to parse hex number") 23 | } 24 | return n 25 | } 26 | 27 | func TestEncryptDecrypt(t *testing.T) { 28 | priv := &PrivateKey{ 29 | PublicKey: PublicKey{ 30 | G: fromHex(generatorHex), 31 | P: fromHex(primeHex), 32 | }, 33 | X: fromHex("42"), 34 | } 35 | priv.Y = new(big.Int).Exp(priv.G, priv.X, priv.P) 36 | 37 | message := []byte("hello world") 38 | c1, c2, err := Encrypt(rand.Reader, &priv.PublicKey, message) 39 | if err != nil { 40 | t.Errorf("error encrypting: %s", err) 41 | } 42 | message2, err := Decrypt(priv, c1, c2) 43 | if err != nil { 44 | t.Errorf("error decrypting: %s", err) 45 | } 46 | if !bytes.Equal(message2, message) { 47 | t.Errorf("decryption failed, got: %x, want: %x", message2, message) 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /tunnel/go.crypto/openpgp/errors/errors.go: -------------------------------------------------------------------------------- 1 | // Copyright 2010 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package errors contains common error types for the OpenPGP packages. 6 | package errors 7 | 8 | import ( 9 | "strconv" 10 | ) 11 | 12 | // A StructuralError is returned when OpenPGP data is found to be syntactically 13 | // invalid. 14 | type StructuralError string 15 | 16 | func (s StructuralError) Error() string { 17 | return "openpgp: invalid data: " + string(s) 18 | } 19 | 20 | // UnsupportedError indicates that, although the OpenPGP data is valid, it 21 | // makes use of currently unimplemented features. 22 | type UnsupportedError string 23 | 24 | func (s UnsupportedError) Error() string { 25 | return "openpgp: unsupported feature: " + string(s) 26 | } 27 | 28 | // InvalidArgumentError indicates that the caller is in error and passed an 29 | // incorrect value. 30 | type InvalidArgumentError string 31 | 32 | func (i InvalidArgumentError) Error() string { 33 | return "openpgp: invalid argument: " + string(i) 34 | } 35 | 36 | // SignatureError indicates that a syntactically valid signature failed to 37 | // validate. 38 | type SignatureError string 39 | 40 | func (b SignatureError) Error() string { 41 | return "openpgp: invalid signature: " + string(b) 42 | } 43 | 44 | type keyIncorrectError int 45 | 46 | func (ki keyIncorrectError) Error() string { 47 | return "openpgp: incorrect key" 48 | } 49 | 50 | var ErrKeyIncorrect error = keyIncorrectError(0) 51 | 52 | type unknownIssuerError int 53 | 54 | func (unknownIssuerError) Error() string { 55 | return "openpgp: signature made by unknown entity" 56 | } 57 | 58 | var ErrUnknownIssuer error = unknownIssuerError(0) 59 | 60 | type keyRevokedError int 61 | 62 | func (keyRevokedError) Error() string { 63 | return "openpgp: signature made by revoked key" 64 | } 65 | 66 | var ErrKeyRevoked error = keyRevokedError(0) 67 | 68 | type UnknownPacketTypeError uint8 69 | 70 | func (upte UnknownPacketTypeError) Error() string { 71 | return "openpgp: unknown packet type: " + strconv.Itoa(int(upte)) 72 | } 73 | -------------------------------------------------------------------------------- /tunnel/go.crypto/openpgp/packet/compressed.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package packet 6 | 7 | import ( 8 | "golang.org/x/crypto/openpgp/errors" 9 | "compress/bzip2" 10 | "compress/flate" 11 | "compress/zlib" 12 | "io" 13 | "strconv" 14 | ) 15 | 16 | // Compressed represents a compressed OpenPGP packet. The decompressed contents 17 | // will contain more OpenPGP packets. See RFC 4880, section 5.6. 18 | type Compressed struct { 19 | Body io.Reader 20 | } 21 | 22 | const ( 23 | NoCompression = flate.NoCompression 24 | BestSpeed = flate.BestSpeed 25 | BestCompression = flate.BestCompression 26 | DefaultCompression = flate.DefaultCompression 27 | ) 28 | 29 | // CompressionConfig contains compressor configuration settings. 30 | type CompressionConfig struct { 31 | // Level is the compression level to use. It must be set to 32 | // between -1 and 9, with -1 causing the compressor to use the 33 | // default compression level, 0 causing the compressor to use 34 | // no compression and 1 to 9 representing increasing (better, 35 | // slower) compression levels. If Level is less than -1 or 36 | // more then 9, a non-nil error will be returned during 37 | // encryption. See the constants above for convenient common 38 | // settings for Level. 39 | Level int 40 | } 41 | 42 | func (c *Compressed) parse(r io.Reader) error { 43 | var buf [1]byte 44 | _, err := readFull(r, buf[:]) 45 | if err != nil { 46 | return err 47 | } 48 | 49 | switch buf[0] { 50 | case 1: 51 | c.Body = flate.NewReader(r) 52 | case 2: 53 | c.Body, err = zlib.NewReader(r) 54 | case 3: 55 | c.Body = bzip2.NewReader(r) 56 | default: 57 | err = errors.UnsupportedError("unknown compression algorithm: " + strconv.Itoa(int(buf[0]))) 58 | } 59 | 60 | return err 61 | } 62 | 63 | // compressedWriterCloser represents the serialized compression stream 64 | // header and the compressor. Its Close() method ensures that both the 65 | // compressor and serialized stream header are closed. Its Write() 66 | // method writes to the compressor. 67 | type compressedWriteCloser struct { 68 | sh io.Closer // Stream Header 69 | c io.WriteCloser // Compressor 70 | } 71 | 72 | func (cwc compressedWriteCloser) Write(p []byte) (int, error) { 73 | return cwc.c.Write(p) 74 | } 75 | 76 | func (cwc compressedWriteCloser) Close() (err error) { 77 | err = cwc.c.Close() 78 | if err != nil { 79 | return err 80 | } 81 | 82 | return cwc.sh.Close() 83 | } 84 | 85 | // SerializeCompressed serializes a compressed data packet to w and 86 | // returns a WriteCloser to which the literal data packets themselves 87 | // can be written and which MUST be closed on completion. If cc is 88 | // nil, sensible defaults will be used to configure the compression 89 | // algorithm. 90 | func SerializeCompressed(w io.WriteCloser, algo CompressionAlgo, cc *CompressionConfig) (literaldata io.WriteCloser, err error) { 91 | compressed, err := serializeStreamHeader(w, packetTypeCompressed) 92 | if err != nil { 93 | return 94 | } 95 | 96 | _, err = compressed.Write([]byte{uint8(algo)}) 97 | if err != nil { 98 | return 99 | } 100 | 101 | level := DefaultCompression 102 | if cc != nil { 103 | level = cc.Level 104 | } 105 | 106 | var compressor io.WriteCloser 107 | switch algo { 108 | case CompressionZIP: 109 | compressor, err = flate.NewWriter(compressed, level) 110 | case CompressionZLIB: 111 | compressor, err = zlib.NewWriterLevel(compressed, level) 112 | default: 113 | s := strconv.Itoa(int(algo)) 114 | err = errors.UnsupportedError("Unsupported compression algorithm: " + s) 115 | } 116 | if err != nil { 117 | return 118 | } 119 | 120 | literaldata = compressedWriteCloser{compressed, compressor} 121 | 122 | return 123 | } 124 | -------------------------------------------------------------------------------- /tunnel/go.crypto/openpgp/packet/compressed_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package packet 6 | 7 | import ( 8 | "bytes" 9 | "encoding/hex" 10 | "io" 11 | "io/ioutil" 12 | "testing" 13 | ) 14 | 15 | func TestCompressed(t *testing.T) { 16 | packet, err := Read(readerFromHex(compressedHex)) 17 | if err != nil { 18 | t.Errorf("failed to read Compressed: %s", err) 19 | return 20 | } 21 | 22 | c, ok := packet.(*Compressed) 23 | if !ok { 24 | t.Error("didn't find Compressed packet") 25 | return 26 | } 27 | 28 | contents, err := ioutil.ReadAll(c.Body) 29 | if err != nil && err != io.EOF { 30 | t.Error(err) 31 | return 32 | } 33 | 34 | expected, _ := hex.DecodeString(compressedExpectedHex) 35 | if !bytes.Equal(expected, contents) { 36 | t.Errorf("got:%x want:%x", contents, expected) 37 | } 38 | } 39 | 40 | const compressedHex = "a3013b2d90c4e02b72e25f727e5e496a5e49b11e1700" 41 | const compressedExpectedHex = "cb1062004d14c8fe636f6e74656e74732e0a" 42 | -------------------------------------------------------------------------------- /tunnel/go.crypto/openpgp/packet/config.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package packet 6 | 7 | import ( 8 | "crypto" 9 | "crypto/rand" 10 | "io" 11 | "time" 12 | ) 13 | 14 | // Config collects a number of parameters along with sensible defaults. 15 | // A nil *Config is valid and results in all default values. 16 | type Config struct { 17 | // Rand provides the source of entropy. 18 | // If nil, the crypto/rand Reader is used. 19 | Rand io.Reader 20 | // DefaultHash is the default hash function to be used. 21 | // If zero, SHA-256 is used. 22 | DefaultHash crypto.Hash 23 | // DefaultCipher is the cipher to be used. 24 | // If zero, AES-128 is used. 25 | DefaultCipher CipherFunction 26 | // Time returns the current time as the number of seconds since the 27 | // epoch. If Time is nil, time.Now is used. 28 | Time func() time.Time 29 | // DefaultCompressionAlgo is the compression algorithm to be 30 | // applied to the plaintext before encryption. If zero, no 31 | // compression is done. 32 | DefaultCompressionAlgo CompressionAlgo 33 | // CompressionConfig configures the compression settings. 34 | CompressionConfig *CompressionConfig 35 | } 36 | 37 | func (c *Config) Random() io.Reader { 38 | if c == nil || c.Rand == nil { 39 | return rand.Reader 40 | } 41 | return c.Rand 42 | } 43 | 44 | func (c *Config) Hash() crypto.Hash { 45 | if c == nil || uint(c.DefaultHash) == 0 { 46 | return crypto.SHA256 47 | } 48 | return c.DefaultHash 49 | } 50 | 51 | func (c *Config) Cipher() CipherFunction { 52 | if c == nil || uint8(c.DefaultCipher) == 0 { 53 | return CipherAES128 54 | } 55 | return c.DefaultCipher 56 | } 57 | 58 | func (c *Config) Now() time.Time { 59 | if c == nil || c.Time == nil { 60 | return time.Now() 61 | } 62 | return c.Time() 63 | } 64 | 65 | func (c *Config) Compression() CompressionAlgo { 66 | if c == nil { 67 | return CompressionNone 68 | } 69 | return c.DefaultCompressionAlgo 70 | } 71 | -------------------------------------------------------------------------------- /tunnel/go.crypto/openpgp/packet/encrypted_key_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package packet 6 | 7 | import ( 8 | "bytes" 9 | "crypto/rsa" 10 | "fmt" 11 | "math/big" 12 | "testing" 13 | ) 14 | 15 | func bigFromBase10(s string) *big.Int { 16 | b, ok := new(big.Int).SetString(s, 10) 17 | if !ok { 18 | panic("bigFromBase10 failed") 19 | } 20 | return b 21 | } 22 | 23 | var encryptedKeyPub = rsa.PublicKey{ 24 | E: 65537, 25 | N: bigFromBase10("115804063926007623305902631768113868327816898845124614648849934718568541074358183759250136204762053879858102352159854352727097033322663029387610959884180306668628526686121021235757016368038585212410610742029286439607686208110250133174279811431933746643015923132833417396844716207301518956640020862630546868823"), 26 | } 27 | 28 | var encryptedKeyRSAPriv = &rsa.PrivateKey{ 29 | PublicKey: encryptedKeyPub, 30 | D: bigFromBase10("32355588668219869544751561565313228297765464314098552250409557267371233892496951383426602439009993875125222579159850054973310859166139474359774543943714622292329487391199285040721944491839695981199720170366763547754915493640685849961780092241140181198779299712578774460837139360803883139311171713302987058393"), 31 | } 32 | 33 | var encryptedKeyPriv = &PrivateKey{ 34 | PublicKey: PublicKey{ 35 | PubKeyAlgo: PubKeyAlgoRSA, 36 | }, 37 | PrivateKey: encryptedKeyRSAPriv, 38 | } 39 | 40 | func TestDecryptingEncryptedKey(t *testing.T) { 41 | const encryptedKeyHex = "c18c032a67d68660df41c70104005789d0de26b6a50c985a02a13131ca829c413a35d0e6fa8d6842599252162808ac7439c72151c8c6183e76923fe3299301414d0c25a2f06a2257db3839e7df0ec964773f6e4c4ac7ff3b48c444237166dd46ba8ff443a5410dc670cb486672fdbe7c9dfafb75b4fea83af3a204fe2a7dfa86bd20122b4f3d2646cbeecb8f7be8" 42 | const expectedKeyHex = "d930363f7e0308c333b9618617ea728963d8df993665ae7be1092d4926fd864b" 43 | 44 | p, err := Read(readerFromHex(encryptedKeyHex)) 45 | if err != nil { 46 | t.Errorf("error from Read: %s", err) 47 | return 48 | } 49 | ek, ok := p.(*EncryptedKey) 50 | if !ok { 51 | t.Errorf("didn't parse an EncryptedKey, got %#v", p) 52 | return 53 | } 54 | 55 | if ek.KeyId != 0x2a67d68660df41c7 || ek.Algo != PubKeyAlgoRSA { 56 | t.Errorf("unexpected EncryptedKey contents: %#v", ek) 57 | return 58 | } 59 | 60 | err = ek.Decrypt(encryptedKeyPriv, nil) 61 | if err != nil { 62 | t.Errorf("error from Decrypt: %s", err) 63 | return 64 | } 65 | 66 | if ek.CipherFunc != CipherAES256 { 67 | t.Errorf("unexpected EncryptedKey contents: %#v", ek) 68 | return 69 | } 70 | 71 | keyHex := fmt.Sprintf("%x", ek.Key) 72 | if keyHex != expectedKeyHex { 73 | t.Errorf("bad key, got %s want %x", keyHex, expectedKeyHex) 74 | } 75 | } 76 | 77 | func TestEncryptingEncryptedKey(t *testing.T) { 78 | key := []byte{1, 2, 3, 4} 79 | const expectedKeyHex = "01020304" 80 | const keyId = 42 81 | 82 | pub := &PublicKey{ 83 | PublicKey: &encryptedKeyPub, 84 | KeyId: keyId, 85 | PubKeyAlgo: PubKeyAlgoRSAEncryptOnly, 86 | } 87 | 88 | buf := new(bytes.Buffer) 89 | err := SerializeEncryptedKey(buf, pub, CipherAES128, key, nil) 90 | if err != nil { 91 | t.Errorf("error writing encrypted key packet: %s", err) 92 | } 93 | 94 | p, err := Read(buf) 95 | if err != nil { 96 | t.Errorf("error from Read: %s", err) 97 | return 98 | } 99 | ek, ok := p.(*EncryptedKey) 100 | if !ok { 101 | t.Errorf("didn't parse an EncryptedKey, got %#v", p) 102 | return 103 | } 104 | 105 | if ek.KeyId != keyId || ek.Algo != PubKeyAlgoRSAEncryptOnly { 106 | t.Errorf("unexpected EncryptedKey contents: %#v", ek) 107 | return 108 | } 109 | 110 | err = ek.Decrypt(encryptedKeyPriv, nil) 111 | if err != nil { 112 | t.Errorf("error from Decrypt: %s", err) 113 | return 114 | } 115 | 116 | if ek.CipherFunc != CipherAES128 { 117 | t.Errorf("unexpected EncryptedKey contents: %#v", ek) 118 | return 119 | } 120 | 121 | keyHex := fmt.Sprintf("%x", ek.Key) 122 | if keyHex != expectedKeyHex { 123 | t.Errorf("bad key, got %s want %x", keyHex, expectedKeyHex) 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /tunnel/go.crypto/openpgp/packet/literal.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package packet 6 | 7 | import ( 8 | "encoding/binary" 9 | "io" 10 | ) 11 | 12 | // LiteralData represents an encrypted file. See RFC 4880, section 5.9. 13 | type LiteralData struct { 14 | IsBinary bool 15 | FileName string 16 | Time uint32 // Unix epoch time. Either creation time or modification time. 0 means undefined. 17 | Body io.Reader 18 | } 19 | 20 | // ForEyesOnly returns whether the contents of the LiteralData have been marked 21 | // as especially sensitive. 22 | func (l *LiteralData) ForEyesOnly() bool { 23 | return l.FileName == "_CONSOLE" 24 | } 25 | 26 | func (l *LiteralData) parse(r io.Reader) (err error) { 27 | var buf [256]byte 28 | 29 | _, err = readFull(r, buf[:2]) 30 | if err != nil { 31 | return 32 | } 33 | 34 | l.IsBinary = buf[0] == 'b' 35 | fileNameLen := int(buf[1]) 36 | 37 | _, err = readFull(r, buf[:fileNameLen]) 38 | if err != nil { 39 | return 40 | } 41 | 42 | l.FileName = string(buf[:fileNameLen]) 43 | 44 | _, err = readFull(r, buf[:4]) 45 | if err != nil { 46 | return 47 | } 48 | 49 | l.Time = binary.BigEndian.Uint32(buf[:4]) 50 | l.Body = r 51 | return 52 | } 53 | 54 | // SerializeLiteral serializes a literal data packet to w and returns a 55 | // WriteCloser to which the data itself can be written and which MUST be closed 56 | // on completion. The fileName is truncated to 255 bytes. 57 | func SerializeLiteral(w io.WriteCloser, isBinary bool, fileName string, time uint32) (plaintext io.WriteCloser, err error) { 58 | var buf [4]byte 59 | buf[0] = 't' 60 | if isBinary { 61 | buf[0] = 'b' 62 | } 63 | if len(fileName) > 255 { 64 | fileName = fileName[:255] 65 | } 66 | buf[1] = byte(len(fileName)) 67 | 68 | inner, err := serializeStreamHeader(w, packetTypeLiteralData) 69 | if err != nil { 70 | return 71 | } 72 | 73 | _, err = inner.Write(buf[:2]) 74 | if err != nil { 75 | return 76 | } 77 | _, err = inner.Write([]byte(fileName)) 78 | if err != nil { 79 | return 80 | } 81 | binary.BigEndian.PutUint32(buf[:], time) 82 | _, err = inner.Write(buf[:]) 83 | if err != nil { 84 | return 85 | } 86 | 87 | plaintext = inner 88 | return 89 | } 90 | -------------------------------------------------------------------------------- /tunnel/go.crypto/openpgp/packet/ocfb_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2010 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package packet 6 | 7 | import ( 8 | "bytes" 9 | "crypto/aes" 10 | "crypto/rand" 11 | "testing" 12 | ) 13 | 14 | var commonKey128 = []byte{0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c} 15 | 16 | func testOCFB(t *testing.T, resync OCFBResyncOption) { 17 | block, err := aes.NewCipher(commonKey128) 18 | if err != nil { 19 | t.Error(err) 20 | return 21 | } 22 | 23 | plaintext := []byte("this is the plaintext, which is long enough to span several blocks.") 24 | randData := make([]byte, block.BlockSize()) 25 | rand.Reader.Read(randData) 26 | ocfb, prefix := NewOCFBEncrypter(block, randData, resync) 27 | ciphertext := make([]byte, len(plaintext)) 28 | ocfb.XORKeyStream(ciphertext, plaintext) 29 | 30 | ocfbdec := NewOCFBDecrypter(block, prefix, resync) 31 | if ocfbdec == nil { 32 | t.Errorf("NewOCFBDecrypter failed (resync: %t)", resync) 33 | return 34 | } 35 | plaintextCopy := make([]byte, len(plaintext)) 36 | ocfbdec.XORKeyStream(plaintextCopy, ciphertext) 37 | 38 | if !bytes.Equal(plaintextCopy, plaintext) { 39 | t.Errorf("got: %x, want: %x (resync: %t)", plaintextCopy, plaintext, resync) 40 | } 41 | } 42 | 43 | func TestOCFB(t *testing.T) { 44 | testOCFB(t, OCFBNoResync) 45 | testOCFB(t, OCFBResync) 46 | } 47 | -------------------------------------------------------------------------------- /tunnel/go.crypto/openpgp/packet/one_pass_signature.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package packet 6 | 7 | import ( 8 | "golang.org/x/crypto/openpgp/errors" 9 | "golang.org/x/crypto/openpgp/s2k" 10 | "crypto" 11 | "encoding/binary" 12 | "io" 13 | "strconv" 14 | ) 15 | 16 | // OnePassSignature represents a one-pass signature packet. See RFC 4880, 17 | // section 5.4. 18 | type OnePassSignature struct { 19 | SigType SignatureType 20 | Hash crypto.Hash 21 | PubKeyAlgo PublicKeyAlgorithm 22 | KeyId uint64 23 | IsLast bool 24 | } 25 | 26 | const onePassSignatureVersion = 3 27 | 28 | func (ops *OnePassSignature) parse(r io.Reader) (err error) { 29 | var buf [13]byte 30 | 31 | _, err = readFull(r, buf[:]) 32 | if err != nil { 33 | return 34 | } 35 | if buf[0] != onePassSignatureVersion { 36 | err = errors.UnsupportedError("one-pass-signature packet version " + strconv.Itoa(int(buf[0]))) 37 | } 38 | 39 | var ok bool 40 | ops.Hash, ok = s2k.HashIdToHash(buf[2]) 41 | if !ok { 42 | return errors.UnsupportedError("hash function: " + strconv.Itoa(int(buf[2]))) 43 | } 44 | 45 | ops.SigType = SignatureType(buf[1]) 46 | ops.PubKeyAlgo = PublicKeyAlgorithm(buf[3]) 47 | ops.KeyId = binary.BigEndian.Uint64(buf[4:12]) 48 | ops.IsLast = buf[12] != 0 49 | return 50 | } 51 | 52 | // Serialize marshals the given OnePassSignature to w. 53 | func (ops *OnePassSignature) Serialize(w io.Writer) error { 54 | var buf [13]byte 55 | buf[0] = onePassSignatureVersion 56 | buf[1] = uint8(ops.SigType) 57 | var ok bool 58 | buf[2], ok = s2k.HashToHashId(ops.Hash) 59 | if !ok { 60 | return errors.UnsupportedError("hash type: " + strconv.Itoa(int(ops.Hash))) 61 | } 62 | buf[3] = uint8(ops.PubKeyAlgo) 63 | binary.BigEndian.PutUint64(buf[4:12], ops.KeyId) 64 | if ops.IsLast { 65 | buf[12] = 1 66 | } 67 | 68 | if err := serializeHeader(w, packetTypeOnePassSignature, len(buf)); err != nil { 69 | return err 70 | } 71 | _, err := w.Write(buf[:]) 72 | return err 73 | } 74 | -------------------------------------------------------------------------------- /tunnel/go.crypto/openpgp/packet/opaque_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package packet 6 | 7 | import ( 8 | "bytes" 9 | "encoding/hex" 10 | "io" 11 | "testing" 12 | ) 13 | 14 | // Test packet.Read error handling in OpaquePacket.Parse, 15 | // which attempts to re-read an OpaquePacket as a supported 16 | // Packet type. 17 | func TestOpaqueParseReason(t *testing.T) { 18 | buf, err := hex.DecodeString(UnsupportedKeyHex) 19 | if err != nil { 20 | t.Fatal(err) 21 | } 22 | or := NewOpaqueReader(bytes.NewBuffer(buf)) 23 | count := 0 24 | badPackets := 0 25 | var uid *UserId 26 | for { 27 | op, err := or.Next() 28 | if err == io.EOF { 29 | break 30 | } else if err != nil { 31 | t.Errorf("#%d: opaque read error: %v", count, err) 32 | break 33 | } 34 | // try to parse opaque packet 35 | p, err := op.Parse() 36 | switch pkt := p.(type) { 37 | case *UserId: 38 | uid = pkt 39 | case *OpaquePacket: 40 | // If an OpaquePacket can't re-parse, packet.Read 41 | // certainly had its reasons. 42 | if pkt.Reason == nil { 43 | t.Errorf("#%d: opaque packet, no reason", count) 44 | } else { 45 | badPackets++ 46 | } 47 | } 48 | count++ 49 | } 50 | 51 | const expectedBad = 3 52 | // Test post-conditions, make sure we actually parsed packets as expected. 53 | if badPackets != expectedBad { 54 | t.Errorf("unexpected # unparseable packets: %d (want %d)", badPackets, expectedBad) 55 | } 56 | if uid == nil { 57 | t.Errorf("failed to find expected UID in unsupported keyring") 58 | } else if uid.Id != "Armin M. Warda " { 59 | t.Errorf("unexpected UID: %v", uid.Id) 60 | } 61 | } 62 | 63 | // This key material has public key and signature packet versions modified to 64 | // an unsupported value (1), so that trying to parse the OpaquePacket to 65 | // a typed packet will get an error. It also contains a GnuPG trust packet. 66 | // (Created with: od -An -t x1 pubring.gpg | xargs | sed 's/ //g') 67 | const UnsupportedKeyHex = `988d012e7a18a20000010400d6ac00d92b89c1f4396c243abb9b76d2e9673ad63483291fed88e22b82e255e441c078c6abbbf7d2d195e50b62eeaa915b85b0ec20c225ce2c64c167cacb6e711daf2e45da4a8356a059b8160e3b3628ac0dd8437b31f06d53d6e8ea4214d4a26406a6b63e1001406ef23e0bb3069fac9a99a91f77dfafd5de0f188a5da5e3c9000511b42741726d696e204d2e205761726461203c7761726461406e657068696c696d2e727568722e64653e8900950105102e8936c705d1eb399e58489901013f0e03ff5a0c4f421e34fcfa388129166420c08cd76987bcdec6f01bd0271459a85cc22048820dd4e44ac2c7d23908d540f54facf1b36b0d9c20488781ce9dca856531e76e2e846826e9951338020a03a09b57aa5faa82e9267458bd76105399885ac35af7dc1cbb6aaed7c39e1039f3b5beda2c0e916bd38560509bab81235d1a0ead83b0020000` 68 | -------------------------------------------------------------------------------- /tunnel/go.crypto/openpgp/packet/private_key_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package packet 6 | 7 | import ( 8 | "testing" 9 | "time" 10 | ) 11 | 12 | var privateKeyTests = []struct { 13 | privateKeyHex string 14 | creationTime time.Time 15 | }{ 16 | { 17 | privKeyRSAHex, 18 | time.Unix(0x4cc349a8, 0), 19 | }, 20 | { 21 | privKeyElGamalHex, 22 | time.Unix(0x4df9ee1a, 0), 23 | }, 24 | } 25 | 26 | func TestPrivateKeyRead(t *testing.T) { 27 | for i, test := range privateKeyTests { 28 | packet, err := Read(readerFromHex(test.privateKeyHex)) 29 | if err != nil { 30 | t.Errorf("#%d: failed to parse: %s", i, err) 31 | continue 32 | } 33 | 34 | privKey := packet.(*PrivateKey) 35 | 36 | if !privKey.Encrypted { 37 | t.Errorf("#%d: private key isn't encrypted", i) 38 | continue 39 | } 40 | 41 | err = privKey.Decrypt([]byte("testing")) 42 | if err != nil { 43 | t.Errorf("#%d: failed to decrypt: %s", i, err) 44 | continue 45 | } 46 | 47 | if !privKey.CreationTime.Equal(test.creationTime) || privKey.Encrypted { 48 | t.Errorf("#%d: bad result, got: %#v", i, privKey) 49 | } 50 | } 51 | } 52 | 53 | // Generated with `gpg --export-secret-keys "Test Key 2"` 54 | const privKeyRSAHex = "9501fe044cc349a8010400b70ca0010e98c090008d45d1ee8f9113bd5861fd57b88bacb7c68658747663f1e1a3b5a98f32fda6472373c024b97359cd2efc88ff60f77751adfbf6af5e615e6a1408cfad8bf0cea30b0d5f53aa27ad59089ba9b15b7ebc2777a25d7b436144027e3bcd203909f147d0e332b240cf63d3395f5dfe0df0a6c04e8655af7eacdf0011010001fe0303024a252e7d475fd445607de39a265472aa74a9320ba2dac395faa687e9e0336aeb7e9a7397e511b5afd9dc84557c80ac0f3d4d7bfec5ae16f20d41c8c84a04552a33870b930420e230e179564f6d19bb153145e76c33ae993886c388832b0fa042ddda7f133924f3854481533e0ede31d51278c0519b29abc3bf53da673e13e3e1214b52413d179d7f66deee35cac8eacb060f78379d70ef4af8607e68131ff529439668fc39c9ce6dfef8a5ac234d234802cbfb749a26107db26406213ae5c06d4673253a3cbee1fcbae58d6ab77e38d6e2c0e7c6317c48e054edadb5a40d0d48acb44643d998139a8a66bb820be1f3f80185bc777d14b5954b60effe2448a036d565c6bc0b915fcea518acdd20ab07bc1529f561c58cd044f723109b93f6fd99f876ff891d64306b5d08f48bab59f38695e9109c4dec34013ba3153488ce070268381ba923ee1eb77125b36afcb4347ec3478c8f2735b06ef17351d872e577fa95d0c397c88c71b59629a36aec" 55 | 56 | // Generated by `gpg --export-secret-keys` followed by a manual extraction of 57 | // the ElGamal subkey from the packets. 58 | const privKeyElGamalHex = "9d0157044df9ee1a100400eb8e136a58ec39b582629cdadf830bc64e0a94ed8103ca8bb247b27b11b46d1d25297ef4bcc3071785ba0c0bedfe89eabc5287fcc0edf81ab5896c1c8e4b20d27d79813c7aede75320b33eaeeaa586edc00fd1036c10133e6ba0ff277245d0d59d04b2b3421b7244aca5f4a8d870c6f1c1fbff9e1c26699a860b9504f35ca1d700030503fd1ededd3b840795be6d9ccbe3c51ee42e2f39233c432b831ddd9c4e72b7025a819317e47bf94f9ee316d7273b05d5fcf2999c3a681f519b1234bbfa6d359b4752bd9c3f77d6b6456cde152464763414ca130f4e91d91041432f90620fec0e6d6b5116076c2985d5aeaae13be492b9b329efcaf7ee25120159a0a30cd976b42d7afe030302dae7eb80db744d4960c4df930d57e87fe81412eaace9f900e6c839817a614ddb75ba6603b9417c33ea7b6c93967dfa2bcff3fa3c74a5ce2c962db65b03aece14c96cbd0038fc" 59 | -------------------------------------------------------------------------------- /tunnel/go.crypto/openpgp/packet/public_key_v3_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package packet 6 | 7 | import ( 8 | "bytes" 9 | "encoding/hex" 10 | "testing" 11 | "time" 12 | ) 13 | 14 | var pubKeyV3Test = struct { 15 | hexFingerprint string 16 | creationTime time.Time 17 | pubKeyAlgo PublicKeyAlgorithm 18 | keyId uint64 19 | keyIdString string 20 | keyIdShort string 21 | }{ 22 | "103BECF5BD1E837C89D19E98487767F7", 23 | time.Unix(779753634, 0), 24 | PubKeyAlgoRSA, 25 | 0xDE0F188A5DA5E3C9, 26 | "DE0F188A5DA5E3C9", 27 | "5DA5E3C9"} 28 | 29 | func TestPublicKeyV3Read(t *testing.T) { 30 | i, test := 0, pubKeyV3Test 31 | packet, err := Read(v3KeyReader(t)) 32 | if err != nil { 33 | t.Fatalf("#%d: Read error: %s", i, err) 34 | } 35 | pk, ok := packet.(*PublicKeyV3) 36 | if !ok { 37 | t.Fatalf("#%d: failed to parse, got: %#v", i, packet) 38 | } 39 | if pk.PubKeyAlgo != test.pubKeyAlgo { 40 | t.Errorf("#%d: bad public key algorithm got:%x want:%x", i, pk.PubKeyAlgo, test.pubKeyAlgo) 41 | } 42 | if !pk.CreationTime.Equal(test.creationTime) { 43 | t.Errorf("#%d: bad creation time got:%v want:%v", i, pk.CreationTime, test.creationTime) 44 | } 45 | expectedFingerprint, _ := hex.DecodeString(test.hexFingerprint) 46 | if !bytes.Equal(expectedFingerprint, pk.Fingerprint[:]) { 47 | t.Errorf("#%d: bad fingerprint got:%x want:%x", i, pk.Fingerprint[:], expectedFingerprint) 48 | } 49 | if pk.KeyId != test.keyId { 50 | t.Errorf("#%d: bad keyid got:%x want:%x", i, pk.KeyId, test.keyId) 51 | } 52 | if g, e := pk.KeyIdString(), test.keyIdString; g != e { 53 | t.Errorf("#%d: bad KeyIdString got:%q want:%q", i, g, e) 54 | } 55 | if g, e := pk.KeyIdShortString(), test.keyIdShort; g != e { 56 | t.Errorf("#%d: bad KeyIdShortString got:%q want:%q", i, g, e) 57 | } 58 | } 59 | 60 | func TestPublicKeyV3Serialize(t *testing.T) { 61 | //for i, test := range pubKeyV3Tests { 62 | i := 0 63 | packet, err := Read(v3KeyReader(t)) 64 | if err != nil { 65 | t.Fatalf("#%d: Read error: %s", i, err) 66 | } 67 | pk, ok := packet.(*PublicKeyV3) 68 | if !ok { 69 | t.Fatalf("#%d: failed to parse, got: %#v", i, packet) 70 | } 71 | var serializeBuf bytes.Buffer 72 | if err = pk.Serialize(&serializeBuf); err != nil { 73 | t.Fatalf("#%d: failed to serialize: %s", i, err) 74 | } 75 | 76 | if packet, err = Read(bytes.NewBuffer(serializeBuf.Bytes())); err != nil { 77 | t.Fatalf("#%d: Read error (from serialized data): %s", i, err) 78 | } 79 | if pk, ok = packet.(*PublicKeyV3); !ok { 80 | t.Fatalf("#%d: failed to parse serialized data, got: %#v", i, packet) 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /tunnel/go.crypto/openpgp/packet/reader.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package packet 6 | 7 | import ( 8 | "golang.org/x/crypto/openpgp/errors" 9 | "io" 10 | ) 11 | 12 | // Reader reads packets from an io.Reader and allows packets to be 'unread' so 13 | // that they result from the next call to Next. 14 | type Reader struct { 15 | q []Packet 16 | readers []io.Reader 17 | } 18 | 19 | // Next returns the most recently unread Packet, or reads another packet from 20 | // the top-most io.Reader. Unknown packet types are skipped. 21 | func (r *Reader) Next() (p Packet, err error) { 22 | if len(r.q) > 0 { 23 | p = r.q[len(r.q)-1] 24 | r.q = r.q[:len(r.q)-1] 25 | return 26 | } 27 | 28 | for len(r.readers) > 0 { 29 | p, err = Read(r.readers[len(r.readers)-1]) 30 | if err == nil { 31 | return 32 | } 33 | if err == io.EOF { 34 | r.readers = r.readers[:len(r.readers)-1] 35 | continue 36 | } 37 | if _, ok := err.(errors.UnknownPacketTypeError); !ok { 38 | return nil, err 39 | } 40 | } 41 | 42 | return nil, io.EOF 43 | } 44 | 45 | // Push causes the Reader to start reading from a new io.Reader. When an EOF 46 | // error is seen from the new io.Reader, it is popped and the Reader continues 47 | // to read from the next most recent io.Reader. 48 | func (r *Reader) Push(reader io.Reader) { 49 | r.readers = append(r.readers, reader) 50 | } 51 | 52 | // Unread causes the given Packet to be returned from the next call to Next. 53 | func (r *Reader) Unread(p Packet) { 54 | r.q = append(r.q, p) 55 | } 56 | 57 | func NewReader(r io.Reader) *Reader { 58 | return &Reader{ 59 | q: nil, 60 | readers: []io.Reader{r}, 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /tunnel/go.crypto/openpgp/packet/signature_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package packet 6 | 7 | import ( 8 | "bytes" 9 | "crypto" 10 | "encoding/hex" 11 | "testing" 12 | ) 13 | 14 | func TestSignatureRead(t *testing.T) { 15 | packet, err := Read(readerFromHex(signatureDataHex)) 16 | if err != nil { 17 | t.Error(err) 18 | return 19 | } 20 | sig, ok := packet.(*Signature) 21 | if !ok || sig.SigType != SigTypeBinary || sig.PubKeyAlgo != PubKeyAlgoRSA || sig.Hash != crypto.SHA1 { 22 | t.Errorf("failed to parse, got: %#v", packet) 23 | } 24 | } 25 | 26 | func TestSignatureReserialize(t *testing.T) { 27 | packet, _ := Read(readerFromHex(signatureDataHex)) 28 | sig := packet.(*Signature) 29 | out := new(bytes.Buffer) 30 | err := sig.Serialize(out) 31 | if err != nil { 32 | t.Errorf("error reserializing: %s", err) 33 | return 34 | } 35 | 36 | expected, _ := hex.DecodeString(signatureDataHex) 37 | if !bytes.Equal(expected, out.Bytes()) { 38 | t.Errorf("output doesn't match input (got vs expected):\n%s\n%s", hex.Dump(out.Bytes()), hex.Dump(expected)) 39 | } 40 | } 41 | 42 | const signatureDataHex = "c2c05c04000102000605024cb45112000a0910ab105c91af38fb158f8d07ff5596ea368c5efe015bed6e78348c0f033c931d5f2ce5db54ce7f2a7e4b4ad64db758d65a7a71773edeab7ba2a9e0908e6a94a1175edd86c1d843279f045b021a6971a72702fcbd650efc393c5474d5b59a15f96d2eaad4c4c426797e0dcca2803ef41c6ff234d403eec38f31d610c344c06f2401c262f0993b2e66cad8a81ebc4322c723e0d4ba09fe917e8777658307ad8329adacba821420741009dfe87f007759f0982275d028a392c6ed983a0d846f890b36148c7358bdb8a516007fac760261ecd06076813831a36d0459075d1befa245ae7f7fb103d92ca759e9498fe60ef8078a39a3beda510deea251ea9f0a7f0df6ef42060f20780360686f3e400e" 43 | -------------------------------------------------------------------------------- /tunnel/go.crypto/openpgp/packet/signature_v3_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package packet 6 | 7 | import ( 8 | "bytes" 9 | "crypto" 10 | "encoding/hex" 11 | "io" 12 | "io/ioutil" 13 | "testing" 14 | 15 | "golang.org/x/crypto/openpgp/armor" 16 | ) 17 | 18 | func TestSignatureV3Read(t *testing.T) { 19 | r := v3KeyReader(t) 20 | Read(r) // Skip public key 21 | Read(r) // Skip uid 22 | packet, err := Read(r) // Signature 23 | if err != nil { 24 | t.Error(err) 25 | return 26 | } 27 | sig, ok := packet.(*SignatureV3) 28 | if !ok || sig.SigType != SigTypeGenericCert || sig.PubKeyAlgo != PubKeyAlgoRSA || sig.Hash != crypto.MD5 { 29 | t.Errorf("failed to parse, got: %#v", packet) 30 | } 31 | } 32 | 33 | func TestSignatureV3Reserialize(t *testing.T) { 34 | r := v3KeyReader(t) 35 | Read(r) // Skip public key 36 | Read(r) // Skip uid 37 | packet, err := Read(r) 38 | if err != nil { 39 | t.Error(err) 40 | return 41 | } 42 | sig := packet.(*SignatureV3) 43 | out := new(bytes.Buffer) 44 | if err = sig.Serialize(out); err != nil { 45 | t.Errorf("error reserializing: %s", err) 46 | return 47 | } 48 | expected, err := ioutil.ReadAll(v3KeyReader(t)) 49 | if err != nil { 50 | t.Error(err) 51 | return 52 | } 53 | expected = expected[4+141+4+39:] // See pgpdump offsets below, this is where the sig starts 54 | if !bytes.Equal(expected, out.Bytes()) { 55 | t.Errorf("output doesn't match input (got vs expected):\n%s\n%s", hex.Dump(out.Bytes()), hex.Dump(expected)) 56 | } 57 | } 58 | 59 | func v3KeyReader(t *testing.T) io.Reader { 60 | armorBlock, err := armor.Decode(bytes.NewBufferString(keySigV3Armor)) 61 | if err != nil { 62 | t.Fatalf("armor Decode failed: %v", err) 63 | } 64 | return armorBlock.Body 65 | } 66 | 67 | // keySigV3Armor is some V3 public key I found in an SKS dump. 68 | // Old: Public Key Packet(tag 6)(141 bytes) 69 | // Ver 4 - new 70 | // Public key creation time - Fri Sep 16 17:13:54 CDT 1994 71 | // Pub alg - unknown(pub 0) 72 | // Unknown public key(pub 0) 73 | // Old: User ID Packet(tag 13)(39 bytes) 74 | // User ID - Armin M. Warda 75 | // Old: Signature Packet(tag 2)(149 bytes) 76 | // Ver 4 - new 77 | // Sig type - unknown(05) 78 | // Pub alg - ElGamal Encrypt-Only(pub 16) 79 | // Hash alg - unknown(hash 46) 80 | // Hashed Sub: unknown(sub 81, critical)(1988 bytes) 81 | const keySigV3Armor = `-----BEGIN PGP PUBLIC KEY BLOCK----- 82 | Version: SKS 1.0.10 83 | 84 | mI0CLnoYogAAAQQA1qwA2SuJwfQ5bCQ6u5t20ulnOtY0gykf7YjiK4LiVeRBwHjGq7v30tGV 85 | 5Qti7qqRW4Ww7CDCJc4sZMFnystucR2vLkXaSoNWoFm4Fg47NiisDdhDezHwbVPW6OpCFNSi 86 | ZAamtj4QAUBu8j4LswafrJqZqR9336/V3g8Yil2l48kABRG0J0FybWluIE0uIFdhcmRhIDx3 87 | YXJkYUBuZXBoaWxpbS5ydWhyLmRlPoiVAgUQLok2xwXR6zmeWEiZAQE/DgP/WgxPQh40/Po4 88 | gSkWZCDAjNdph7zexvAb0CcUWahcwiBIgg3U5ErCx9I5CNVA9U+s8bNrDZwgSIeBzp3KhWUx 89 | 524uhGgm6ZUTOAIKA6CbV6pfqoLpJnRYvXYQU5mIWsNa99wcu2qu18OeEDnztb7aLA6Ra9OF 90 | YFCbq4EjXRoOrYM= 91 | =LPjs 92 | -----END PGP PUBLIC KEY BLOCK-----` 93 | -------------------------------------------------------------------------------- /tunnel/go.crypto/openpgp/packet/symmetric_key_encrypted_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package packet 6 | 7 | import ( 8 | "bytes" 9 | "encoding/hex" 10 | "io" 11 | "io/ioutil" 12 | "testing" 13 | ) 14 | 15 | func TestSymmetricKeyEncrypted(t *testing.T) { 16 | buf := readerFromHex(symmetricallyEncryptedHex) 17 | packet, err := Read(buf) 18 | if err != nil { 19 | t.Errorf("failed to read SymmetricKeyEncrypted: %s", err) 20 | return 21 | } 22 | ske, ok := packet.(*SymmetricKeyEncrypted) 23 | if !ok { 24 | t.Error("didn't find SymmetricKeyEncrypted packet") 25 | return 26 | } 27 | err = ske.Decrypt([]byte("password")) 28 | if err != nil { 29 | t.Error(err) 30 | return 31 | } 32 | 33 | packet, err = Read(buf) 34 | if err != nil { 35 | t.Errorf("failed to read SymmetricallyEncrypted: %s", err) 36 | return 37 | } 38 | se, ok := packet.(*SymmetricallyEncrypted) 39 | if !ok { 40 | t.Error("didn't find SymmetricallyEncrypted packet") 41 | return 42 | } 43 | r, err := se.Decrypt(ske.CipherFunc, ske.Key) 44 | if err != nil { 45 | t.Error(err) 46 | return 47 | } 48 | 49 | contents, err := ioutil.ReadAll(r) 50 | if err != nil && err != io.EOF { 51 | t.Error(err) 52 | return 53 | } 54 | 55 | expectedContents, _ := hex.DecodeString(symmetricallyEncryptedContentsHex) 56 | if !bytes.Equal(expectedContents, contents) { 57 | t.Errorf("bad contents got:%x want:%x", contents, expectedContents) 58 | } 59 | } 60 | 61 | const symmetricallyEncryptedHex = "8c0d04030302371a0b38d884f02060c91cf97c9973b8e58e028e9501708ccfe618fb92afef7fa2d80ddadd93cf" 62 | const symmetricallyEncryptedContentsHex = "cb1062004d14c4df636f6e74656e74732e0a" 63 | 64 | func TestSerializeSymmetricKeyEncrypted(t *testing.T) { 65 | buf := bytes.NewBuffer(nil) 66 | passphrase := []byte("testing") 67 | config := &Config{ 68 | DefaultCipher: CipherAES128, 69 | } 70 | 71 | key, err := SerializeSymmetricKeyEncrypted(buf, passphrase, config) 72 | if err != nil { 73 | t.Errorf("failed to serialize: %s", err) 74 | return 75 | } 76 | 77 | p, err := Read(buf) 78 | if err != nil { 79 | t.Errorf("failed to reparse: %s", err) 80 | return 81 | } 82 | ske, ok := p.(*SymmetricKeyEncrypted) 83 | if !ok { 84 | t.Errorf("parsed a different packet type: %#v", p) 85 | return 86 | } 87 | 88 | if !ske.Encrypted { 89 | t.Errorf("SKE not encrypted but should be") 90 | } 91 | if ske.CipherFunc != config.DefaultCipher { 92 | t.Errorf("SKE cipher function is %d (expected %d)", ske.CipherFunc, config.DefaultCipher) 93 | } 94 | err = ske.Decrypt(passphrase) 95 | if err != nil { 96 | t.Errorf("failed to decrypt reparsed SKE: %s", err) 97 | return 98 | } 99 | if !bytes.Equal(key, ske.Key) { 100 | t.Errorf("keys don't match after Decrpyt: %x (original) vs %x (parsed)", key, ske.Key) 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /tunnel/go.crypto/openpgp/packet/symmetrically_encrypted_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package packet 6 | 7 | import ( 8 | "bytes" 9 | "golang.org/x/crypto/openpgp/errors" 10 | "crypto/sha1" 11 | "encoding/hex" 12 | "io" 13 | "io/ioutil" 14 | "testing" 15 | ) 16 | 17 | // TestReader wraps a []byte and returns reads of a specific length. 18 | type testReader struct { 19 | data []byte 20 | stride int 21 | } 22 | 23 | func (t *testReader) Read(buf []byte) (n int, err error) { 24 | n = t.stride 25 | if n > len(t.data) { 26 | n = len(t.data) 27 | } 28 | if n > len(buf) { 29 | n = len(buf) 30 | } 31 | copy(buf, t.data) 32 | t.data = t.data[n:] 33 | if len(t.data) == 0 { 34 | err = io.EOF 35 | } 36 | return 37 | } 38 | 39 | func testMDCReader(t *testing.T) { 40 | mdcPlaintext, _ := hex.DecodeString(mdcPlaintextHex) 41 | 42 | for stride := 1; stride < len(mdcPlaintext)/2; stride++ { 43 | r := &testReader{data: mdcPlaintext, stride: stride} 44 | mdcReader := &seMDCReader{in: r, h: sha1.New()} 45 | body, err := ioutil.ReadAll(mdcReader) 46 | if err != nil { 47 | t.Errorf("stride: %d, error: %s", stride, err) 48 | continue 49 | } 50 | if !bytes.Equal(body, mdcPlaintext[:len(mdcPlaintext)-22]) { 51 | t.Errorf("stride: %d: bad contents %x", stride, body) 52 | continue 53 | } 54 | 55 | err = mdcReader.Close() 56 | if err != nil { 57 | t.Errorf("stride: %d, error on Close: %s", stride, err) 58 | } 59 | } 60 | 61 | mdcPlaintext[15] ^= 80 62 | 63 | r := &testReader{data: mdcPlaintext, stride: 2} 64 | mdcReader := &seMDCReader{in: r, h: sha1.New()} 65 | _, err := ioutil.ReadAll(mdcReader) 66 | if err != nil { 67 | t.Errorf("corruption test, error: %s", err) 68 | return 69 | } 70 | err = mdcReader.Close() 71 | if err == nil { 72 | t.Error("corruption: no error") 73 | } else if _, ok := err.(*errors.SignatureError); !ok { 74 | t.Errorf("corruption: expected SignatureError, got: %s", err) 75 | } 76 | } 77 | 78 | const mdcPlaintextHex = "a302789c3b2d93c4e0eb9aba22283539b3203335af44a134afb800c849cb4c4de10200aff40b45d31432c80cb384299a0655966d6939dfdeed1dddf980" 79 | 80 | func TestSerialize(t *testing.T) { 81 | buf := bytes.NewBuffer(nil) 82 | c := CipherAES128 83 | key := make([]byte, c.KeySize()) 84 | 85 | w, err := SerializeSymmetricallyEncrypted(buf, c, key, nil) 86 | if err != nil { 87 | t.Errorf("error from SerializeSymmetricallyEncrypted: %s", err) 88 | return 89 | } 90 | 91 | contents := []byte("hello world\n") 92 | 93 | w.Write(contents) 94 | w.Close() 95 | 96 | p, err := Read(buf) 97 | if err != nil { 98 | t.Errorf("error from Read: %s", err) 99 | return 100 | } 101 | 102 | se, ok := p.(*SymmetricallyEncrypted) 103 | if !ok { 104 | t.Errorf("didn't read a *SymmetricallyEncrypted") 105 | return 106 | } 107 | 108 | r, err := se.Decrypt(c, key) 109 | if err != nil { 110 | t.Errorf("error from Decrypt: %s", err) 111 | return 112 | } 113 | 114 | contentsCopy := bytes.NewBuffer(nil) 115 | _, err = io.Copy(contentsCopy, r) 116 | if err != nil { 117 | t.Errorf("error from io.Copy: %s", err) 118 | return 119 | } 120 | if !bytes.Equal(contentsCopy.Bytes(), contents) { 121 | t.Errorf("contents not equal got: %x want: %x", contentsCopy.Bytes(), contents) 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /tunnel/go.crypto/openpgp/packet/userattribute.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package packet 6 | 7 | import ( 8 | "bytes" 9 | "image" 10 | "image/jpeg" 11 | "io" 12 | "io/ioutil" 13 | ) 14 | 15 | const UserAttrImageSubpacket = 1 16 | 17 | // UserAttribute is capable of storing other types of data about a user 18 | // beyond name, email and a text comment. In practice, user attributes are typically used 19 | // to store a signed thumbnail photo JPEG image of the user. 20 | // See RFC 4880, section 5.12. 21 | type UserAttribute struct { 22 | Contents []*OpaqueSubpacket 23 | } 24 | 25 | // NewUserAttributePhoto creates a user attribute packet 26 | // containing the given images. 27 | func NewUserAttributePhoto(photos ...image.Image) (uat *UserAttribute, err error) { 28 | uat = new(UserAttribute) 29 | for _, photo := range photos { 30 | var buf bytes.Buffer 31 | // RFC 4880, Section 5.12.1. 32 | data := []byte{ 33 | 0x10, 0x00, // Little-endian image header length (16 bytes) 34 | 0x01, // Image header version 1 35 | 0x01, // JPEG 36 | 0, 0, 0, 0, // 12 reserved octets, must be all zero. 37 | 0, 0, 0, 0, 38 | 0, 0, 0, 0} 39 | if _, err = buf.Write(data); err != nil { 40 | return 41 | } 42 | if err = jpeg.Encode(&buf, photo, nil); err != nil { 43 | return 44 | } 45 | uat.Contents = append(uat.Contents, &OpaqueSubpacket{ 46 | SubType: UserAttrImageSubpacket, 47 | Contents: buf.Bytes()}) 48 | } 49 | return 50 | } 51 | 52 | // NewUserAttribute creates a new user attribute packet containing the given subpackets. 53 | func NewUserAttribute(contents ...*OpaqueSubpacket) *UserAttribute { 54 | return &UserAttribute{Contents: contents} 55 | } 56 | 57 | func (uat *UserAttribute) parse(r io.Reader) (err error) { 58 | // RFC 4880, section 5.13 59 | b, err := ioutil.ReadAll(r) 60 | if err != nil { 61 | return 62 | } 63 | uat.Contents, err = OpaqueSubpackets(b) 64 | return 65 | } 66 | 67 | // Serialize marshals the user attribute to w in the form of an OpenPGP packet, including 68 | // header. 69 | func (uat *UserAttribute) Serialize(w io.Writer) (err error) { 70 | var buf bytes.Buffer 71 | for _, sp := range uat.Contents { 72 | sp.Serialize(&buf) 73 | } 74 | if err = serializeHeader(w, packetTypeUserAttribute, buf.Len()); err != nil { 75 | return err 76 | } 77 | _, err = w.Write(buf.Bytes()) 78 | return 79 | } 80 | 81 | // ImageData returns zero or more byte slices, each containing 82 | // JPEG File Interchange Format (JFIF), for each photo in the 83 | // the user attribute packet. 84 | func (uat *UserAttribute) ImageData() (imageData [][]byte) { 85 | for _, sp := range uat.Contents { 86 | if sp.SubType == UserAttrImageSubpacket && len(sp.Contents) > 16 { 87 | imageData = append(imageData, sp.Contents[16:]) 88 | } 89 | } 90 | return 91 | } 92 | -------------------------------------------------------------------------------- /tunnel/go.crypto/openpgp/packet/userid_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package packet 6 | 7 | import ( 8 | "testing" 9 | ) 10 | 11 | var userIdTests = []struct { 12 | id string 13 | name, comment, email string 14 | }{ 15 | {"", "", "", ""}, 16 | {"John Smith", "John Smith", "", ""}, 17 | {"John Smith ()", "John Smith", "", ""}, 18 | {"John Smith () <>", "John Smith", "", ""}, 19 | {"(comment", "", "comment", ""}, 20 | {"(comment)", "", "comment", ""}, 21 | {" sdfk", "", "", "email"}, 23 | {" John Smith ( Comment ) asdkflj < email > lksdfj", "John Smith", "Comment", "email"}, 24 | {" John Smith < email > lksdfj", "John Smith", "", "email"}, 25 | {"("}, 50 | {"foo", "bar", "", "foo (bar)"}, 51 | {"foo", "", "baz", "foo "}, 52 | {"", "bar", "baz", "(bar) "}, 53 | {"foo", "bar", "baz", "foo (bar) "}, 54 | } 55 | 56 | func TestNewUserId(t *testing.T) { 57 | for i, test := range newUserIdTests { 58 | uid := NewUserId(test.name, test.comment, test.email) 59 | if uid == nil { 60 | t.Errorf("#%d: returned nil", i) 61 | continue 62 | } 63 | if uid.Id != test.id { 64 | t.Errorf("#%d: got '%s', want '%s'", i, uid.Id, test.id) 65 | } 66 | } 67 | } 68 | 69 | var invalidNewUserIdTests = []struct { 70 | name, comment, email string 71 | }{ 72 | {"foo(", "", ""}, 73 | {"foo<", "", ""}, 74 | {"", "bar)", ""}, 75 | {"", "bar<", ""}, 76 | {"", "", "baz>"}, 77 | {"", "", "baz)"}, 78 | {"", "", "baz\x00"}, 79 | } 80 | 81 | func TestNewUserIdWithInvalidInput(t *testing.T) { 82 | for i, test := range invalidNewUserIdTests { 83 | if uid := NewUserId(test.name, test.comment, test.email); uid != nil { 84 | t.Errorf("#%d: returned non-nil value: %#v", i, uid) 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /tunnel/go.crypto/openpgp/s2k/s2k_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package s2k 6 | 7 | import ( 8 | "bytes" 9 | "crypto/rand" 10 | "crypto/sha1" 11 | "encoding/hex" 12 | "testing" 13 | ) 14 | 15 | var saltedTests = []struct { 16 | in, out string 17 | }{ 18 | {"hello", "10295ac1"}, 19 | {"world", "ac587a5e"}, 20 | {"foo", "4dda8077"}, 21 | {"bar", "bd8aac6b9ea9cae04eae6a91c6133b58b5d9a61c14f355516ed9370456"}, 22 | {"x", "f1d3f289"}, 23 | {"xxxxxxxxxxxxxxxxxxxxxxx", "e00d7b45"}, 24 | } 25 | 26 | func TestSalted(t *testing.T) { 27 | h := sha1.New() 28 | salt := [4]byte{1, 2, 3, 4} 29 | 30 | for i, test := range saltedTests { 31 | expected, _ := hex.DecodeString(test.out) 32 | out := make([]byte, len(expected)) 33 | Salted(out, h, []byte(test.in), salt[:]) 34 | if !bytes.Equal(expected, out) { 35 | t.Errorf("#%d, got: %x want: %x", i, out, expected) 36 | } 37 | } 38 | } 39 | 40 | var iteratedTests = []struct { 41 | in, out string 42 | }{ 43 | {"hello", "83126105"}, 44 | {"world", "6fa317f9"}, 45 | {"foo", "8fbc35b9"}, 46 | {"bar", "2af5a99b54f093789fd657f19bd245af7604d0f6ae06f66602a46a08ae"}, 47 | {"x", "5a684dfe"}, 48 | {"xxxxxxxxxxxxxxxxxxxxxxx", "18955174"}, 49 | } 50 | 51 | func TestIterated(t *testing.T) { 52 | h := sha1.New() 53 | salt := [4]byte{4, 3, 2, 1} 54 | 55 | for i, test := range iteratedTests { 56 | expected, _ := hex.DecodeString(test.out) 57 | out := make([]byte, len(expected)) 58 | Iterated(out, h, []byte(test.in), salt[:], 31) 59 | if !bytes.Equal(expected, out) { 60 | t.Errorf("#%d, got: %x want: %x", i, out, expected) 61 | } 62 | } 63 | } 64 | 65 | var parseTests = []struct { 66 | spec, in, out string 67 | }{ 68 | /* Simple with SHA1 */ 69 | {"0002", "hello", "aaf4c61d"}, 70 | /* Salted with SHA1 */ 71 | {"01020102030405060708", "hello", "f4f7d67e"}, 72 | /* Iterated with SHA1 */ 73 | {"03020102030405060708f1", "hello", "f2a57b7c"}, 74 | } 75 | 76 | func TestParse(t *testing.T) { 77 | for i, test := range parseTests { 78 | spec, _ := hex.DecodeString(test.spec) 79 | buf := bytes.NewBuffer(spec) 80 | f, err := Parse(buf) 81 | if err != nil { 82 | t.Errorf("%d: Parse returned error: %s", i, err) 83 | continue 84 | } 85 | 86 | expected, _ := hex.DecodeString(test.out) 87 | out := make([]byte, len(expected)) 88 | f(out, []byte(test.in)) 89 | if !bytes.Equal(out, expected) { 90 | t.Errorf("%d: output got: %x want: %x", i, out, expected) 91 | } 92 | if testing.Short() { 93 | break 94 | } 95 | } 96 | } 97 | 98 | func TestSerialize(t *testing.T) { 99 | buf := bytes.NewBuffer(nil) 100 | key := make([]byte, 16) 101 | passphrase := []byte("testing") 102 | err := Serialize(buf, key, rand.Reader, passphrase) 103 | if err != nil { 104 | t.Errorf("failed to serialize: %s", err) 105 | return 106 | } 107 | 108 | f, err := Parse(buf) 109 | if err != nil { 110 | t.Errorf("failed to reparse: %s", err) 111 | return 112 | } 113 | key2 := make([]byte, len(key)) 114 | f(key2, passphrase) 115 | if !bytes.Equal(key2, key) { 116 | t.Errorf("keys don't match: %x (serialied) vs %x (parsed)", key, key2) 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /tunnel/go.crypto/pbkdf2/pbkdf2.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | /* 6 | Package pbkdf2 implements the key derivation function PBKDF2 as defined in RFC 7 | 2898 / PKCS #5 v2.0. 8 | 9 | A key derivation function is useful when encrypting data based on a password 10 | or any other not-fully-random data. It uses a pseudorandom function to derive 11 | a secure encryption key based on the password. 12 | 13 | While v2.0 of the standard defines only one pseudorandom function to use, 14 | HMAC-SHA1, the drafted v2.1 specification allows use of all five FIPS Approved 15 | Hash Functions SHA-1, SHA-224, SHA-256, SHA-384 and SHA-512 for HMAC. To 16 | choose, you can pass the `New` functions from the different SHA packages to 17 | pbkdf2.Key. 18 | */ 19 | package pbkdf2 20 | 21 | import ( 22 | "crypto/hmac" 23 | "hash" 24 | ) 25 | 26 | // Key derives a key from the password, salt and iteration count, returning a 27 | // []byte of length keylen that can be used as cryptographic key. The key is 28 | // derived based on the method described as PBKDF2 with the HMAC variant using 29 | // the supplied hash function. 30 | // 31 | // For example, to use a HMAC-SHA-1 based PBKDF2 key derivation function, you 32 | // can get a derived key for e.g. AES-256 (which needs a 32-byte key) by 33 | // doing: 34 | // 35 | // dk := pbkdf2.Key([]byte("some password"), salt, 4096, 32, sha1.New) 36 | // 37 | // Remember to get a good random salt. At least 8 bytes is recommended by the 38 | // RFC. 39 | // 40 | // Using a higher iteration count will increase the cost of an exhaustive 41 | // search but will also make derivation proportionally slower. 42 | func Key(password, salt []byte, iter, keyLen int, h func() hash.Hash) []byte { 43 | prf := hmac.New(h, password) 44 | hashLen := prf.Size() 45 | numBlocks := (keyLen + hashLen - 1) / hashLen 46 | 47 | var buf [4]byte 48 | dk := make([]byte, 0, numBlocks*hashLen) 49 | U := make([]byte, hashLen) 50 | for block := 1; block <= numBlocks; block++ { 51 | // N.B.: || means concatenation, ^ means XOR 52 | // for each block T_i = U_1 ^ U_2 ^ ... ^ U_iter 53 | // U_1 = PRF(password, salt || uint(i)) 54 | prf.Reset() 55 | prf.Write(salt) 56 | buf[0] = byte(block >> 24) 57 | buf[1] = byte(block >> 16) 58 | buf[2] = byte(block >> 8) 59 | buf[3] = byte(block) 60 | prf.Write(buf[:4]) 61 | dk = prf.Sum(dk) 62 | T := dk[len(dk)-hashLen:] 63 | copy(U, T) 64 | 65 | // U_n = PRF(password, U_(n-1)) 66 | for n := 2; n <= iter; n++ { 67 | prf.Reset() 68 | prf.Write(U) 69 | U = U[:0] 70 | U = prf.Sum(U) 71 | for x := range U { 72 | T[x] ^= U[x] 73 | } 74 | } 75 | } 76 | return dk[:keyLen] 77 | } 78 | -------------------------------------------------------------------------------- /tunnel/go.crypto/pbkdf2/pbkdf2_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package pbkdf2 6 | 7 | import ( 8 | "bytes" 9 | "crypto/sha1" 10 | "crypto/sha256" 11 | "hash" 12 | "testing" 13 | ) 14 | 15 | type testVector struct { 16 | password string 17 | salt string 18 | iter int 19 | output []byte 20 | } 21 | 22 | // Test vectors from RFC 6070, http://tools.ietf.org/html/rfc6070 23 | var sha1TestVectors = []testVector{ 24 | { 25 | "password", 26 | "salt", 27 | 1, 28 | []byte{ 29 | 0x0c, 0x60, 0xc8, 0x0f, 0x96, 0x1f, 0x0e, 0x71, 30 | 0xf3, 0xa9, 0xb5, 0x24, 0xaf, 0x60, 0x12, 0x06, 31 | 0x2f, 0xe0, 0x37, 0xa6, 32 | }, 33 | }, 34 | { 35 | "password", 36 | "salt", 37 | 2, 38 | []byte{ 39 | 0xea, 0x6c, 0x01, 0x4d, 0xc7, 0x2d, 0x6f, 0x8c, 40 | 0xcd, 0x1e, 0xd9, 0x2a, 0xce, 0x1d, 0x41, 0xf0, 41 | 0xd8, 0xde, 0x89, 0x57, 42 | }, 43 | }, 44 | { 45 | "password", 46 | "salt", 47 | 4096, 48 | []byte{ 49 | 0x4b, 0x00, 0x79, 0x01, 0xb7, 0x65, 0x48, 0x9a, 50 | 0xbe, 0xad, 0x49, 0xd9, 0x26, 0xf7, 0x21, 0xd0, 51 | 0x65, 0xa4, 0x29, 0xc1, 52 | }, 53 | }, 54 | // // This one takes too long 55 | // { 56 | // "password", 57 | // "salt", 58 | // 16777216, 59 | // []byte{ 60 | // 0xee, 0xfe, 0x3d, 0x61, 0xcd, 0x4d, 0xa4, 0xe4, 61 | // 0xe9, 0x94, 0x5b, 0x3d, 0x6b, 0xa2, 0x15, 0x8c, 62 | // 0x26, 0x34, 0xe9, 0x84, 63 | // }, 64 | // }, 65 | { 66 | "passwordPASSWORDpassword", 67 | "saltSALTsaltSALTsaltSALTsaltSALTsalt", 68 | 4096, 69 | []byte{ 70 | 0x3d, 0x2e, 0xec, 0x4f, 0xe4, 0x1c, 0x84, 0x9b, 71 | 0x80, 0xc8, 0xd8, 0x36, 0x62, 0xc0, 0xe4, 0x4a, 72 | 0x8b, 0x29, 0x1a, 0x96, 0x4c, 0xf2, 0xf0, 0x70, 73 | 0x38, 74 | }, 75 | }, 76 | { 77 | "pass\000word", 78 | "sa\000lt", 79 | 4096, 80 | []byte{ 81 | 0x56, 0xfa, 0x6a, 0xa7, 0x55, 0x48, 0x09, 0x9d, 82 | 0xcc, 0x37, 0xd7, 0xf0, 0x34, 0x25, 0xe0, 0xc3, 83 | }, 84 | }, 85 | } 86 | 87 | // Test vectors from 88 | // http://stackoverflow.com/questions/5130513/pbkdf2-hmac-sha2-test-vectors 89 | var sha256TestVectors = []testVector{ 90 | { 91 | "password", 92 | "salt", 93 | 1, 94 | []byte{ 95 | 0x12, 0x0f, 0xb6, 0xcf, 0xfc, 0xf8, 0xb3, 0x2c, 96 | 0x43, 0xe7, 0x22, 0x52, 0x56, 0xc4, 0xf8, 0x37, 97 | 0xa8, 0x65, 0x48, 0xc9, 98 | }, 99 | }, 100 | { 101 | "password", 102 | "salt", 103 | 2, 104 | []byte{ 105 | 0xae, 0x4d, 0x0c, 0x95, 0xaf, 0x6b, 0x46, 0xd3, 106 | 0x2d, 0x0a, 0xdf, 0xf9, 0x28, 0xf0, 0x6d, 0xd0, 107 | 0x2a, 0x30, 0x3f, 0x8e, 108 | }, 109 | }, 110 | { 111 | "password", 112 | "salt", 113 | 4096, 114 | []byte{ 115 | 0xc5, 0xe4, 0x78, 0xd5, 0x92, 0x88, 0xc8, 0x41, 116 | 0xaa, 0x53, 0x0d, 0xb6, 0x84, 0x5c, 0x4c, 0x8d, 117 | 0x96, 0x28, 0x93, 0xa0, 118 | }, 119 | }, 120 | { 121 | "passwordPASSWORDpassword", 122 | "saltSALTsaltSALTsaltSALTsaltSALTsalt", 123 | 4096, 124 | []byte{ 125 | 0x34, 0x8c, 0x89, 0xdb, 0xcb, 0xd3, 0x2b, 0x2f, 126 | 0x32, 0xd8, 0x14, 0xb8, 0x11, 0x6e, 0x84, 0xcf, 127 | 0x2b, 0x17, 0x34, 0x7e, 0xbc, 0x18, 0x00, 0x18, 128 | 0x1c, 129 | }, 130 | }, 131 | { 132 | "pass\000word", 133 | "sa\000lt", 134 | 4096, 135 | []byte{ 136 | 0x89, 0xb6, 0x9d, 0x05, 0x16, 0xf8, 0x29, 0x89, 137 | 0x3c, 0x69, 0x62, 0x26, 0x65, 0x0a, 0x86, 0x87, 138 | }, 139 | }, 140 | } 141 | 142 | func testHash(t *testing.T, h func() hash.Hash, hashName string, vectors []testVector) { 143 | for i, v := range vectors { 144 | o := Key([]byte(v.password), []byte(v.salt), v.iter, len(v.output), h) 145 | if !bytes.Equal(o, v.output) { 146 | t.Errorf("%s %d: expected %x, got %x", hashName, i, v.output, o) 147 | } 148 | } 149 | } 150 | 151 | func TestWithHMACSHA1(t *testing.T) { 152 | testHash(t, sha1.New, "SHA1", sha1TestVectors) 153 | } 154 | 155 | func TestWithHMACSHA256(t *testing.T) { 156 | testHash(t, sha256.New, "SHA256", sha256TestVectors) 157 | } 158 | -------------------------------------------------------------------------------- /tunnel/go.crypto/poly1305/const_amd64.s: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // This code was translated into a form compatible with 6a from the public 6 | // domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html 7 | 8 | // +build amd64,!gccgo 9 | 10 | DATA ·SCALE(SB)/8, $0x37F4000000000000 11 | GLOBL ·SCALE(SB), $8 12 | DATA ·TWO32(SB)/8, $0x41F0000000000000 13 | GLOBL ·TWO32(SB), $8 14 | DATA ·TWO64(SB)/8, $0x43F0000000000000 15 | GLOBL ·TWO64(SB), $8 16 | DATA ·TWO96(SB)/8, $0x45F0000000000000 17 | GLOBL ·TWO96(SB), $8 18 | DATA ·ALPHA32(SB)/8, $0x45E8000000000000 19 | GLOBL ·ALPHA32(SB), $8 20 | DATA ·ALPHA64(SB)/8, $0x47E8000000000000 21 | GLOBL ·ALPHA64(SB), $8 22 | DATA ·ALPHA96(SB)/8, $0x49E8000000000000 23 | GLOBL ·ALPHA96(SB), $8 24 | DATA ·ALPHA130(SB)/8, $0x4C08000000000000 25 | GLOBL ·ALPHA130(SB), $8 26 | DATA ·DOFFSET0(SB)/8, $0x4330000000000000 27 | GLOBL ·DOFFSET0(SB), $8 28 | DATA ·DOFFSET1(SB)/8, $0x4530000000000000 29 | GLOBL ·DOFFSET1(SB), $8 30 | DATA ·DOFFSET2(SB)/8, $0x4730000000000000 31 | GLOBL ·DOFFSET2(SB), $8 32 | DATA ·DOFFSET3(SB)/8, $0x4930000000000000 33 | GLOBL ·DOFFSET3(SB), $8 34 | DATA ·DOFFSET3MINUSTWO128(SB)/8, $0x492FFFFE00000000 35 | GLOBL ·DOFFSET3MINUSTWO128(SB), $8 36 | DATA ·HOFFSET0(SB)/8, $0x43300001FFFFFFFB 37 | GLOBL ·HOFFSET0(SB), $8 38 | DATA ·HOFFSET1(SB)/8, $0x45300001FFFFFFFE 39 | GLOBL ·HOFFSET1(SB), $8 40 | DATA ·HOFFSET2(SB)/8, $0x47300001FFFFFFFE 41 | GLOBL ·HOFFSET2(SB), $8 42 | DATA ·HOFFSET3(SB)/8, $0x49300003FFFFFFFE 43 | GLOBL ·HOFFSET3(SB), $8 44 | DATA ·ROUNDING(SB)/2, $0x137f 45 | GLOBL ·ROUNDING(SB), $2 46 | -------------------------------------------------------------------------------- /tunnel/go.crypto/poly1305/poly1305.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | /* 6 | Package poly1305 implements Poly1305 one-time message authentication code as specified in http://cr.yp.to/mac/poly1305-20050329.pdf. 7 | 8 | Poly1305 is a fast, one-time authentication function. It is infeasible for an 9 | attacker to generate an authenticator for a message without the key. However, a 10 | key must only be used for a single message. Authenticating two different 11 | messages with the same key allows an attacker to forge authenticators for other 12 | messages with the same key. 13 | 14 | Poly1305 was originally coupled with AES in order to make Poly1305-AES. AES was 15 | used with a fixed key in order to generate one-time keys from an nonce. 16 | However, in this package AES isn't used and the one-time key is specified 17 | directly. 18 | */ 19 | package poly1305 20 | 21 | import "crypto/subtle" 22 | 23 | // TagSize is the size, in bytes, of a poly1305 authenticator. 24 | const TagSize = 16 25 | 26 | // Verify returns true if mac is a valid authenticator for m with the given 27 | // key. 28 | func Verify(mac *[16]byte, m []byte, key *[32]byte) bool { 29 | var tmp [16]byte 30 | Sum(&tmp, m, key) 31 | return subtle.ConstantTimeCompare(tmp[:], mac[:]) == 1 32 | } 33 | -------------------------------------------------------------------------------- /tunnel/go.crypto/poly1305/poly1305_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package poly1305 6 | 7 | import ( 8 | "bytes" 9 | "testing" 10 | ) 11 | 12 | var testData = []struct { 13 | in, k, correct []byte 14 | }{ 15 | { 16 | []byte("Hello world!"), 17 | []byte("this is 32-byte key for Poly1305"), 18 | []byte{0xa6, 0xf7, 0x45, 0x00, 0x8f, 0x81, 0xc9, 0x16, 0xa2, 0x0d, 0xcc, 0x74, 0xee, 0xf2, 0xb2, 0xf0}, 19 | }, 20 | { 21 | make([]byte, 32), 22 | []byte("this is 32-byte key for Poly1305"), 23 | []byte{0x49, 0xec, 0x78, 0x09, 0x0e, 0x48, 0x1e, 0xc6, 0xc2, 0x6b, 0x33, 0xb9, 0x1c, 0xcc, 0x03, 0x07}, 24 | }, 25 | { 26 | make([]byte, 2007), 27 | []byte("this is 32-byte key for Poly1305"), 28 | []byte{0xda, 0x84, 0xbc, 0xab, 0x02, 0x67, 0x6c, 0x38, 0xcd, 0xb0, 0x15, 0x60, 0x42, 0x74, 0xc2, 0xaa}, 29 | }, 30 | { 31 | make([]byte, 2007), 32 | make([]byte, 32), 33 | make([]byte, 16), 34 | }, 35 | } 36 | 37 | func TestSum(t *testing.T) { 38 | var out [16]byte 39 | var key [32]byte 40 | 41 | for i, v := range testData { 42 | copy(key[:], v.k) 43 | Sum(&out, v.in, &key) 44 | if !bytes.Equal(out[:], v.correct) { 45 | t.Errorf("%d: expected %x, got %x", i, v.correct, out[:]) 46 | } 47 | } 48 | } 49 | 50 | func Benchmark1K(b *testing.B) { 51 | b.StopTimer() 52 | var out [16]byte 53 | var key [32]byte 54 | in := make([]byte, 1024) 55 | b.SetBytes(int64(len(in))) 56 | b.StartTimer() 57 | 58 | for i := 0; i < b.N; i++ { 59 | Sum(&out, in, &key) 60 | } 61 | } 62 | 63 | func Benchmark64(b *testing.B) { 64 | b.StopTimer() 65 | var out [16]byte 66 | var key [32]byte 67 | in := make([]byte, 64) 68 | b.SetBytes(int64(len(in))) 69 | b.StartTimer() 70 | 71 | for i := 0; i < b.N; i++ { 72 | Sum(&out, in, &key) 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /tunnel/go.crypto/poly1305/sum_amd64.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build amd64,!gccgo 6 | 7 | package poly1305 8 | 9 | // This function is implemented in poly1305_amd64.s 10 | 11 | //go:noescape 12 | 13 | func poly1305(out *[16]byte, m *byte, mlen uint64, key *[32]byte) 14 | 15 | // Sum generates an authenticator for m using a one-time key and puts the 16 | // 16-byte result into out. Authenticating two different messages with the same 17 | // key allows an attacker to forge messages at will. 18 | func Sum(out *[16]byte, m []byte, key *[32]byte) { 19 | var mPtr *byte 20 | if len(m) > 0 { 21 | mPtr = &m[0] 22 | } 23 | poly1305(out, mPtr, uint64(len(m)), key) 24 | } 25 | -------------------------------------------------------------------------------- /tunnel/go.crypto/ripemd160/ripemd160.go: -------------------------------------------------------------------------------- 1 | // Copyright 2010 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package ripemd160 implements the RIPEMD-160 hash algorithm. 6 | package ripemd160 7 | 8 | // RIPEMD-160 is designed by by Hans Dobbertin, Antoon Bosselaers, and Bart 9 | // Preneel with specifications available at: 10 | // http://homes.esat.kuleuven.be/~cosicart/pdf/AB-9601/AB-9601.pdf. 11 | 12 | import ( 13 | "crypto" 14 | "hash" 15 | ) 16 | 17 | func init() { 18 | crypto.RegisterHash(crypto.RIPEMD160, New) 19 | } 20 | 21 | // The size of the checksum in bytes. 22 | const Size = 20 23 | 24 | // The block size of the hash algorithm in bytes. 25 | const BlockSize = 64 26 | 27 | const ( 28 | _s0 = 0x67452301 29 | _s1 = 0xefcdab89 30 | _s2 = 0x98badcfe 31 | _s3 = 0x10325476 32 | _s4 = 0xc3d2e1f0 33 | ) 34 | 35 | // digest represents the partial evaluation of a checksum. 36 | type digest struct { 37 | s [5]uint32 // running context 38 | x [BlockSize]byte // temporary buffer 39 | nx int // index into x 40 | tc uint64 // total count of bytes processed 41 | } 42 | 43 | func (d *digest) Reset() { 44 | d.s[0], d.s[1], d.s[2], d.s[3], d.s[4] = _s0, _s1, _s2, _s3, _s4 45 | d.nx = 0 46 | d.tc = 0 47 | } 48 | 49 | // New returns a new hash.Hash computing the checksum. 50 | func New() hash.Hash { 51 | result := new(digest) 52 | result.Reset() 53 | return result 54 | } 55 | 56 | func (d *digest) Size() int { return Size } 57 | 58 | func (d *digest) BlockSize() int { return BlockSize } 59 | 60 | func (d *digest) Write(p []byte) (nn int, err error) { 61 | nn = len(p) 62 | d.tc += uint64(nn) 63 | if d.nx > 0 { 64 | n := len(p) 65 | if n > BlockSize-d.nx { 66 | n = BlockSize - d.nx 67 | } 68 | for i := 0; i < n; i++ { 69 | d.x[d.nx+i] = p[i] 70 | } 71 | d.nx += n 72 | if d.nx == BlockSize { 73 | _Block(d, d.x[0:]) 74 | d.nx = 0 75 | } 76 | p = p[n:] 77 | } 78 | n := _Block(d, p) 79 | p = p[n:] 80 | if len(p) > 0 { 81 | d.nx = copy(d.x[:], p) 82 | } 83 | return 84 | } 85 | 86 | func (d0 *digest) Sum(in []byte) []byte { 87 | // Make a copy of d0 so that caller can keep writing and summing. 88 | d := *d0 89 | 90 | // Padding. Add a 1 bit and 0 bits until 56 bytes mod 64. 91 | tc := d.tc 92 | var tmp [64]byte 93 | tmp[0] = 0x80 94 | if tc%64 < 56 { 95 | d.Write(tmp[0 : 56-tc%64]) 96 | } else { 97 | d.Write(tmp[0 : 64+56-tc%64]) 98 | } 99 | 100 | // Length in bits. 101 | tc <<= 3 102 | for i := uint(0); i < 8; i++ { 103 | tmp[i] = byte(tc >> (8 * i)) 104 | } 105 | d.Write(tmp[0:8]) 106 | 107 | if d.nx != 0 { 108 | panic("d.nx != 0") 109 | } 110 | 111 | var digest [Size]byte 112 | for i, s := range d.s { 113 | digest[i*4] = byte(s) 114 | digest[i*4+1] = byte(s >> 8) 115 | digest[i*4+2] = byte(s >> 16) 116 | digest[i*4+3] = byte(s >> 24) 117 | } 118 | 119 | return append(in, digest[:]...) 120 | } 121 | -------------------------------------------------------------------------------- /tunnel/go.crypto/ripemd160/ripemd160_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2010 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package ripemd160 6 | 7 | // Test vectors are from: 8 | // http://homes.esat.kuleuven.be/~bosselae/ripemd160.html 9 | 10 | import ( 11 | "fmt" 12 | "io" 13 | "testing" 14 | ) 15 | 16 | type mdTest struct { 17 | out string 18 | in string 19 | } 20 | 21 | var vectors = [...]mdTest{ 22 | {"9c1185a5c5e9fc54612808977ee8f548b2258d31", ""}, 23 | {"0bdc9d2d256b3ee9daae347be6f4dc835a467ffe", "a"}, 24 | {"8eb208f7e05d987a9b044a8e98c6b087f15a0bfc", "abc"}, 25 | {"5d0689ef49d2fae572b881b123a85ffa21595f36", "message digest"}, 26 | {"f71c27109c692c1b56bbdceb5b9d2865b3708dbc", "abcdefghijklmnopqrstuvwxyz"}, 27 | {"12a053384a9c0c88e405a06c27dcf49ada62eb2b", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"}, 28 | {"b0e20b6e3116640286ed3a87a5713079b21f5189", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"}, 29 | {"9b752e45573d4b39f4dbd3323cab82bf63326bfb", "12345678901234567890123456789012345678901234567890123456789012345678901234567890"}, 30 | } 31 | 32 | func TestVectors(t *testing.T) { 33 | for i := 0; i < len(vectors); i++ { 34 | tv := vectors[i] 35 | md := New() 36 | for j := 0; j < 3; j++ { 37 | if j < 2 { 38 | io.WriteString(md, tv.in) 39 | } else { 40 | io.WriteString(md, tv.in[0:len(tv.in)/2]) 41 | md.Sum(nil) 42 | io.WriteString(md, tv.in[len(tv.in)/2:]) 43 | } 44 | s := fmt.Sprintf("%x", md.Sum(nil)) 45 | if s != tv.out { 46 | t.Fatalf("RIPEMD-160[%d](%s) = %s, expected %s", j, tv.in, s, tv.out) 47 | } 48 | md.Reset() 49 | } 50 | } 51 | } 52 | 53 | func TestMillionA(t *testing.T) { 54 | md := New() 55 | for i := 0; i < 100000; i++ { 56 | io.WriteString(md, "aaaaaaaaaa") 57 | } 58 | out := "52783243c1697bdbe16d37f97f68f08325dc1528" 59 | s := fmt.Sprintf("%x", md.Sum(nil)) 60 | if s != out { 61 | t.Fatalf("RIPEMD-160 (1 million 'a') = %s, expected %s", s, out) 62 | } 63 | md.Reset() 64 | } 65 | -------------------------------------------------------------------------------- /tunnel/go.crypto/salsa20/salsa/salsa20_amd64.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build amd64,!appengine,!gccgo 6 | 7 | package salsa 8 | 9 | // This function is implemented in salsa2020_amd64.s. 10 | 11 | //go:noescape 12 | 13 | func salsa2020XORKeyStream(out, in *byte, n uint64, nonce, key *byte) 14 | 15 | // XORKeyStream crypts bytes from in to out using the given key and counters. 16 | // In and out may be the same slice but otherwise should not overlap. Counter 17 | // contains the raw salsa20 counter bytes (both nonce and block counter). 18 | func XORKeyStream(out, in []byte, counter *[16]byte, key *[32]byte) { 19 | if len(in) == 0 { 20 | return 21 | } 22 | salsa2020XORKeyStream(&out[0], &in[0], uint64(len(in)), &counter[0], &key[0]) 23 | } 24 | -------------------------------------------------------------------------------- /tunnel/go.crypto/salsa20/salsa/salsa_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package salsa 6 | 7 | import "testing" 8 | 9 | func TestCore208(t *testing.T) { 10 | in := [64]byte{ 11 | 0x7e, 0x87, 0x9a, 0x21, 0x4f, 0x3e, 0xc9, 0x86, 12 | 0x7c, 0xa9, 0x40, 0xe6, 0x41, 0x71, 0x8f, 0x26, 13 | 0xba, 0xee, 0x55, 0x5b, 0x8c, 0x61, 0xc1, 0xb5, 14 | 0x0d, 0xf8, 0x46, 0x11, 0x6d, 0xcd, 0x3b, 0x1d, 15 | 0xee, 0x24, 0xf3, 0x19, 0xdf, 0x9b, 0x3d, 0x85, 16 | 0x14, 0x12, 0x1e, 0x4b, 0x5a, 0xc5, 0xaa, 0x32, 17 | 0x76, 0x02, 0x1d, 0x29, 0x09, 0xc7, 0x48, 0x29, 18 | 0xed, 0xeb, 0xc6, 0x8d, 0xb8, 0xb8, 0xc2, 0x5e} 19 | 20 | out := [64]byte{ 21 | 0xa4, 0x1f, 0x85, 0x9c, 0x66, 0x08, 0xcc, 0x99, 22 | 0x3b, 0x81, 0xca, 0xcb, 0x02, 0x0c, 0xef, 0x05, 23 | 0x04, 0x4b, 0x21, 0x81, 0xa2, 0xfd, 0x33, 0x7d, 24 | 0xfd, 0x7b, 0x1c, 0x63, 0x96, 0x68, 0x2f, 0x29, 25 | 0xb4, 0x39, 0x31, 0x68, 0xe3, 0xc9, 0xe6, 0xbc, 26 | 0xfe, 0x6b, 0xc5, 0xb7, 0xa0, 0x6d, 0x96, 0xba, 27 | 0xe4, 0x24, 0xcc, 0x10, 0x2c, 0x91, 0x74, 0x5c, 28 | 0x24, 0xad, 0x67, 0x3d, 0xc7, 0x61, 0x8f, 0x81, 29 | } 30 | 31 | Core208(&in, &in) 32 | if in != out { 33 | t.Errorf("expected %x, got %x", out, in) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /tunnel/go.crypto/salsa20/salsa20.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | /* 6 | Package salsa20 implements the Salsa20 stream cipher as specified in http://cr.yp.to/snuffle/spec.pdf. 7 | 8 | Salsa20 differs from many other stream ciphers in that it is message orientated 9 | rather than byte orientated. Keystream blocks are not preserved between calls, 10 | therefore each side must encrypt/decrypt data with the same segmentation. 11 | 12 | Another aspect of this difference is that part of the counter is exposed as 13 | an nonce in each call. Encrypting two different messages with the same (key, 14 | nonce) pair leads to trivial plaintext recovery. This is analogous to 15 | encrypting two different messages with the same key with a traditional stream 16 | cipher. 17 | 18 | This package also implements XSalsa20: a version of Salsa20 with a 24-byte 19 | nonce as specified in http://cr.yp.to/snuffle/xsalsa-20081128.pdf. Simply 20 | passing a 24-byte slice as the nonce triggers XSalsa20. 21 | */ 22 | package salsa20 23 | 24 | // TODO(agl): implement XORKeyStream12 and XORKeyStream8 - the reduced round variants of Salsa20. 25 | 26 | import ( 27 | "golang.org/x/crypto/salsa20/salsa" 28 | ) 29 | 30 | // XORKeyStream crypts bytes from in to out using the given key and nonce. In 31 | // and out may be the same slice but otherwise should not overlap. Nonce must 32 | // be either 8 or 24 bytes long. 33 | func XORKeyStream(out, in []byte, nonce []byte, key *[32]byte) { 34 | if len(out) < len(in) { 35 | in = in[:len(out)] 36 | } 37 | 38 | var subNonce [16]byte 39 | 40 | if len(nonce) == 24 { 41 | var subKey [32]byte 42 | var hNonce [16]byte 43 | copy(hNonce[:], nonce[:16]) 44 | salsa.HSalsa20(&subKey, &hNonce, key, &salsa.Sigma) 45 | copy(subNonce[:], nonce[16:]) 46 | key = &subKey 47 | } else if len(nonce) == 8 { 48 | copy(subNonce[:], nonce[:]) 49 | } else { 50 | panic("salsa20: nonce must be 8 or 24 bytes") 51 | } 52 | 53 | salsa.XORKeyStream(out, in, &subNonce, key) 54 | } 55 | -------------------------------------------------------------------------------- /tunnel/go.crypto/sha3/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package sha3 implements the SHA-3 fixed-output-length hash functions and 6 | // the SHAKE variable-output-length hash functions defined by FIPS-202. 7 | // 8 | // Both types of hash function use the "sponge" construction and the Keccak 9 | // permutation. For a detailed specification see http://keccak.noekeon.org/ 10 | // 11 | // 12 | // Guidance 13 | // 14 | // If you aren't sure what function you need, use SHAKE256 with at least 64 15 | // bytes of output. 16 | // 17 | // If you need a secret-key MAC (message authentication code), prepend the 18 | // secret key to the input, hash with SHAKE256 and read at least 32 bytes of 19 | // output. 20 | // 21 | // 22 | // Security strengths 23 | // 24 | // The SHA3-x functions have a security strength against preimage attacks of x 25 | // bits. Since they only produce x bits of output, their collision-resistance 26 | // is only x/2 bits. 27 | // 28 | // The SHAKE-x functions have a generic security strength of x bits against 29 | // all attacks, provided that at least 2x bits of their output is used. 30 | // Requesting more than 2x bits of output does not increase the collision- 31 | // resistance of the SHAKE functions. 32 | // 33 | // 34 | // The sponge construction 35 | // 36 | // A sponge builds a pseudo-random function from a pseudo-random permutation, 37 | // by applying the permutation to a state of "rate + capacity" bytes, but 38 | // hiding "capacity" of the bytes. 39 | // 40 | // A sponge starts out with a zero state. To hash an input using a sponge, up 41 | // to "rate" bytes of the input are XORed into the sponge's state. The sponge 42 | // has thus been "filled up" and the permutation is applied. This process is 43 | // repeated until all the input has been "absorbed". The input is then padded. 44 | // The digest is "squeezed" from the sponge by the same method, except that 45 | // output is copied out. 46 | // 47 | // A sponge is parameterized by its generic security strength, which is equal 48 | // to half its capacity; capacity + rate is equal to the permutation's width. 49 | // 50 | // Since the KeccakF-1600 permutation is 1600 bits (200 bytes) wide, this means 51 | // that security_strength == (1600 - bitrate) / 2. 52 | // 53 | // 54 | // Recommendations, detailed 55 | // 56 | // The SHAKE functions are recommended for most new uses. They can produce 57 | // output of arbitrary length. SHAKE256, with an output length of at least 58 | // 64 bytes, provides 256-bit security against all attacks. 59 | // 60 | // The Keccak team recommends SHAKE256 for most applications upgrading from 61 | // SHA2-512. (NIST chose a much stronger, but much slower, sponge instance 62 | // for SHA3-512.) 63 | // 64 | // The SHA-3 functions are "drop-in" replacements for the SHA-2 functions. 65 | // They produce output of the same length, with the same security strengths 66 | // against all attacks. This means, in particular, that SHA3-256 only has 67 | // 128-bit collision resistance, because its output length is 32 bytes. 68 | package sha3 69 | -------------------------------------------------------------------------------- /tunnel/go.crypto/sha3/hashes.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package sha3 6 | 7 | // This file provides functions for creating instances of the SHA-3 8 | // and SHAKE hash functions, as well as utility functions for hashing 9 | // bytes. 10 | 11 | import ( 12 | "hash" 13 | ) 14 | 15 | // New224 creates a new SHA3-224 hash. 16 | // Its generic security strength is 224 bits against preimage attacks, 17 | // and 112 bits against collision attacks. 18 | func New224() hash.Hash { return &state{rate: 144, outputLen: 28, dsbyte: 0x06} } 19 | 20 | // New256 creates a new SHA3-256 hash. 21 | // Its generic security strength is 256 bits against preimage attacks, 22 | // and 128 bits against collision attacks. 23 | func New256() hash.Hash { return &state{rate: 136, outputLen: 32, dsbyte: 0x06} } 24 | 25 | // New384 creates a new SHA3-384 hash. 26 | // Its generic security strength is 384 bits against preimage attacks, 27 | // and 192 bits against collision attacks. 28 | func New384() hash.Hash { return &state{rate: 104, outputLen: 48, dsbyte: 0x06} } 29 | 30 | // New512 creates a new SHA3-512 hash. 31 | // Its generic security strength is 512 bits against preimage attacks, 32 | // and 256 bits against collision attacks. 33 | func New512() hash.Hash { return &state{rate: 72, outputLen: 64, dsbyte: 0x06} } 34 | 35 | // Sum224 returns the SHA3-224 digest of the data. 36 | func Sum224(data []byte) (digest [28]byte) { 37 | h := New224() 38 | h.Write(data) 39 | h.Sum(digest[:0]) 40 | return 41 | } 42 | 43 | // Sum256 returns the SHA3-256 digest of the data. 44 | func Sum256(data []byte) (digest [32]byte) { 45 | h := New256() 46 | h.Write(data) 47 | h.Sum(digest[:0]) 48 | return 49 | } 50 | 51 | // Sum384 returns the SHA3-384 digest of the data. 52 | func Sum384(data []byte) (digest [48]byte) { 53 | h := New384() 54 | h.Write(data) 55 | h.Sum(digest[:0]) 56 | return 57 | } 58 | 59 | // Sum512 returns the SHA3-512 digest of the data. 60 | func Sum512(data []byte) (digest [64]byte) { 61 | h := New512() 62 | h.Write(data) 63 | h.Sum(digest[:0]) 64 | return 65 | } 66 | -------------------------------------------------------------------------------- /tunnel/go.crypto/sha3/keccakKats.json.deflate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal3d/idok/810ce94e0524888fb180dc6992480781bc7c0bd2/tunnel/go.crypto/sha3/keccakKats.json.deflate -------------------------------------------------------------------------------- /tunnel/go.crypto/sha3/register.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build go1.4 6 | 7 | package sha3 8 | 9 | import ( 10 | "crypto" 11 | ) 12 | 13 | func init() { 14 | crypto.RegisterHash(crypto.SHA3_224, New224) 15 | crypto.RegisterHash(crypto.SHA3_256, New256) 16 | crypto.RegisterHash(crypto.SHA3_384, New384) 17 | crypto.RegisterHash(crypto.SHA3_512, New512) 18 | } 19 | -------------------------------------------------------------------------------- /tunnel/go.crypto/sha3/shake.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package sha3 6 | 7 | // This file defines the ShakeHash interface, and provides 8 | // functions for creating SHAKE instances, as well as utility 9 | // functions for hashing bytes to arbitrary-length output. 10 | 11 | import ( 12 | "io" 13 | ) 14 | 15 | // ShakeHash defines the interface to hash functions that 16 | // support arbitrary-length output. 17 | type ShakeHash interface { 18 | // Write absorbs more data into the hash's state. It panics if input is 19 | // written to it after output has been read from it. 20 | io.Writer 21 | 22 | // Read reads more output from the hash; reading affects the hash's 23 | // state. (ShakeHash.Read is thus very different from Hash.Sum) 24 | // It never returns an error. 25 | io.Reader 26 | 27 | // Clone returns a copy of the ShakeHash in its current state. 28 | Clone() ShakeHash 29 | 30 | // Reset resets the ShakeHash to its initial state. 31 | Reset() 32 | } 33 | 34 | func (d *state) Clone() ShakeHash { 35 | return d.clone() 36 | } 37 | 38 | // NewShake128 creates a new SHAKE128 variable-output-length ShakeHash. 39 | // Its generic security strength is 128 bits against all attacks if at 40 | // least 32 bytes of its output are used. 41 | func NewShake128() ShakeHash { return &state{rate: 168, dsbyte: 0x1f} } 42 | 43 | // NewShake256 creates a new SHAKE128 variable-output-length ShakeHash. 44 | // Its generic security strength is 256 bits against all attacks if 45 | // at least 64 bytes of its output are used. 46 | func NewShake256() ShakeHash { return &state{rate: 136, dsbyte: 0x1f} } 47 | 48 | // ShakeSum128 writes an arbitrary-length digest of data into hash. 49 | func ShakeSum128(hash, data []byte) { 50 | h := NewShake128() 51 | h.Write(data) 52 | h.Read(hash) 53 | } 54 | 55 | // ShakeSum256 writes an arbitrary-length digest of data into hash. 56 | func ShakeSum256(hash, data []byte) { 57 | h := NewShake256() 58 | h.Write(data) 59 | h.Read(hash) 60 | } 61 | -------------------------------------------------------------------------------- /tunnel/go.crypto/ssh/agent/forward.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package agent 6 | 7 | import ( 8 | "errors" 9 | "io" 10 | "net" 11 | "sync" 12 | 13 | "golang.org/x/crypto/ssh" 14 | ) 15 | 16 | // RequestAgentForwarding sets up agent forwarding for the session. 17 | // ForwardToAgent or ForwardToRemote should be called to route 18 | // the authentication requests. 19 | func RequestAgentForwarding(session *ssh.Session) error { 20 | ok, err := session.SendRequest("auth-agent-req@openssh.com", true, nil) 21 | if err != nil { 22 | return err 23 | } 24 | if !ok { 25 | return errors.New("forwarding request denied") 26 | } 27 | return nil 28 | } 29 | 30 | // ForwardToAgent routes authentication requests to the given keyring. 31 | func ForwardToAgent(client *ssh.Client, keyring Agent) error { 32 | channels := client.HandleChannelOpen(channelType) 33 | if channels == nil { 34 | return errors.New("agent: already have handler for " + channelType) 35 | } 36 | 37 | go func() { 38 | for ch := range channels { 39 | channel, reqs, err := ch.Accept() 40 | if err != nil { 41 | continue 42 | } 43 | go ssh.DiscardRequests(reqs) 44 | go func() { 45 | ServeAgent(keyring, channel) 46 | channel.Close() 47 | }() 48 | } 49 | }() 50 | return nil 51 | } 52 | 53 | const channelType = "auth-agent@openssh.com" 54 | 55 | // ForwardToRemote routes authentication requests to the ssh-agent 56 | // process serving on the given unix socket. 57 | func ForwardToRemote(client *ssh.Client, addr string) error { 58 | channels := client.HandleChannelOpen(channelType) 59 | if channels == nil { 60 | return errors.New("agent: already have handler for " + channelType) 61 | } 62 | conn, err := net.Dial("unix", addr) 63 | if err != nil { 64 | return err 65 | } 66 | conn.Close() 67 | 68 | go func() { 69 | for ch := range channels { 70 | channel, reqs, err := ch.Accept() 71 | if err != nil { 72 | continue 73 | } 74 | go ssh.DiscardRequests(reqs) 75 | go forwardUnixSocket(channel, addr) 76 | } 77 | }() 78 | return nil 79 | } 80 | 81 | func forwardUnixSocket(channel ssh.Channel, addr string) { 82 | conn, err := net.Dial("unix", addr) 83 | if err != nil { 84 | return 85 | } 86 | 87 | var wg sync.WaitGroup 88 | wg.Add(2) 89 | go func() { 90 | io.Copy(conn, channel) 91 | conn.(*net.UnixConn).CloseWrite() 92 | wg.Done() 93 | }() 94 | go func() { 95 | io.Copy(channel, conn) 96 | channel.CloseWrite() 97 | wg.Done() 98 | }() 99 | 100 | wg.Wait() 101 | conn.Close() 102 | channel.Close() 103 | } 104 | -------------------------------------------------------------------------------- /tunnel/go.crypto/ssh/agent/server_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package agent 6 | 7 | import ( 8 | "testing" 9 | 10 | "golang.org/x/crypto/ssh" 11 | ) 12 | 13 | func TestServer(t *testing.T) { 14 | c1, c2, err := netPipe() 15 | if err != nil { 16 | t.Fatalf("netPipe: %v", err) 17 | } 18 | defer c1.Close() 19 | defer c2.Close() 20 | client := NewClient(c1) 21 | 22 | go ServeAgent(NewKeyring(), c2) 23 | 24 | testAgentInterface(t, client, testPrivateKeys["rsa"], nil) 25 | } 26 | 27 | func TestLockServer(t *testing.T) { 28 | testLockAgent(NewKeyring(), t) 29 | } 30 | 31 | func TestSetupForwardAgent(t *testing.T) { 32 | a, b, err := netPipe() 33 | if err != nil { 34 | t.Fatalf("netPipe: %v", err) 35 | } 36 | 37 | defer a.Close() 38 | defer b.Close() 39 | 40 | _, socket, cleanup := startAgent(t) 41 | defer cleanup() 42 | 43 | serverConf := ssh.ServerConfig{ 44 | NoClientAuth: true, 45 | } 46 | serverConf.AddHostKey(testSigners["rsa"]) 47 | incoming := make(chan *ssh.ServerConn, 1) 48 | go func() { 49 | conn, _, _, err := ssh.NewServerConn(a, &serverConf) 50 | if err != nil { 51 | t.Fatalf("Server: %v", err) 52 | } 53 | incoming <- conn 54 | }() 55 | 56 | conf := ssh.ClientConfig{} 57 | conn, chans, reqs, err := ssh.NewClientConn(b, "", &conf) 58 | if err != nil { 59 | t.Fatalf("NewClientConn: %v", err) 60 | } 61 | client := ssh.NewClient(conn, chans, reqs) 62 | 63 | if err := ForwardToRemote(client, socket); err != nil { 64 | t.Fatalf("SetupForwardAgent: %v", err) 65 | } 66 | 67 | server := <-incoming 68 | ch, reqs, err := server.OpenChannel(channelType, nil) 69 | if err != nil { 70 | t.Fatalf("OpenChannel(%q): %v", channelType, err) 71 | } 72 | go ssh.DiscardRequests(reqs) 73 | 74 | agentClient := NewClient(ch) 75 | testAgentInterface(t, agentClient, testPrivateKeys["rsa"], nil) 76 | conn.Close() 77 | } 78 | -------------------------------------------------------------------------------- /tunnel/go.crypto/ssh/agent/testdata_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // IMPLEMENTOR NOTE: To avoid a package loop, this file is in three places: 6 | // ssh/, ssh/agent, and ssh/test/. It should be kept in sync across all three 7 | // instances. 8 | 9 | package agent 10 | 11 | import ( 12 | "crypto/rand" 13 | "fmt" 14 | 15 | "golang.org/x/crypto/ssh" 16 | "golang.org/x/crypto/ssh/testdata" 17 | ) 18 | 19 | var ( 20 | testPrivateKeys map[string]interface{} 21 | testSigners map[string]ssh.Signer 22 | testPublicKeys map[string]ssh.PublicKey 23 | ) 24 | 25 | func init() { 26 | var err error 27 | 28 | n := len(testdata.PEMBytes) 29 | testPrivateKeys = make(map[string]interface{}, n) 30 | testSigners = make(map[string]ssh.Signer, n) 31 | testPublicKeys = make(map[string]ssh.PublicKey, n) 32 | for t, k := range testdata.PEMBytes { 33 | testPrivateKeys[t], err = ssh.ParseRawPrivateKey(k) 34 | if err != nil { 35 | panic(fmt.Sprintf("Unable to parse test key %s: %v", t, err)) 36 | } 37 | testSigners[t], err = ssh.NewSignerFromKey(testPrivateKeys[t]) 38 | if err != nil { 39 | panic(fmt.Sprintf("Unable to create signer for test key %s: %v", t, err)) 40 | } 41 | testPublicKeys[t] = testSigners[t].PublicKey() 42 | } 43 | 44 | // Create a cert and sign it for use in tests. 45 | testCert := &ssh.Certificate{ 46 | Nonce: []byte{}, // To pass reflect.DeepEqual after marshal & parse, this must be non-nil 47 | ValidPrincipals: []string{"gopher1", "gopher2"}, // increases test coverage 48 | ValidAfter: 0, // unix epoch 49 | ValidBefore: ssh.CertTimeInfinity, // The end of currently representable time. 50 | Reserved: []byte{}, // To pass reflect.DeepEqual after marshal & parse, this must be non-nil 51 | Key: testPublicKeys["ecdsa"], 52 | SignatureKey: testPublicKeys["rsa"], 53 | Permissions: ssh.Permissions{ 54 | CriticalOptions: map[string]string{}, 55 | Extensions: map[string]string{}, 56 | }, 57 | } 58 | testCert.SignCert(rand.Reader, testSigners["rsa"]) 59 | testPrivateKeys["cert"] = testPrivateKeys["ecdsa"] 60 | testSigners["cert"], err = ssh.NewCertSigner(testCert, testSigners["ecdsa"]) 61 | if err != nil { 62 | panic(fmt.Sprintf("Unable to create certificate signer: %v", err)) 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /tunnel/go.crypto/ssh/benchmark_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package ssh 6 | 7 | import ( 8 | "errors" 9 | "io" 10 | "net" 11 | "testing" 12 | ) 13 | 14 | type server struct { 15 | *ServerConn 16 | chans <-chan NewChannel 17 | } 18 | 19 | func newServer(c net.Conn, conf *ServerConfig) (*server, error) { 20 | sconn, chans, reqs, err := NewServerConn(c, conf) 21 | if err != nil { 22 | return nil, err 23 | } 24 | go DiscardRequests(reqs) 25 | return &server{sconn, chans}, nil 26 | } 27 | 28 | func (s *server) Accept() (NewChannel, error) { 29 | n, ok := <-s.chans 30 | if !ok { 31 | return nil, io.EOF 32 | } 33 | return n, nil 34 | } 35 | 36 | func sshPipe() (Conn, *server, error) { 37 | c1, c2, err := netPipe() 38 | if err != nil { 39 | return nil, nil, err 40 | } 41 | 42 | clientConf := ClientConfig{ 43 | User: "user", 44 | } 45 | serverConf := ServerConfig{ 46 | NoClientAuth: true, 47 | } 48 | serverConf.AddHostKey(testSigners["ecdsa"]) 49 | done := make(chan *server, 1) 50 | go func() { 51 | server, err := newServer(c2, &serverConf) 52 | if err != nil { 53 | done <- nil 54 | } 55 | done <- server 56 | }() 57 | 58 | client, _, reqs, err := NewClientConn(c1, "", &clientConf) 59 | if err != nil { 60 | return nil, nil, err 61 | } 62 | 63 | server := <-done 64 | if server == nil { 65 | return nil, nil, errors.New("server handshake failed.") 66 | } 67 | go DiscardRequests(reqs) 68 | 69 | return client, server, nil 70 | } 71 | 72 | func BenchmarkEndToEnd(b *testing.B) { 73 | b.StopTimer() 74 | 75 | client, server, err := sshPipe() 76 | if err != nil { 77 | b.Fatalf("sshPipe: %v", err) 78 | } 79 | 80 | defer client.Close() 81 | defer server.Close() 82 | 83 | size := (1 << 20) 84 | input := make([]byte, size) 85 | output := make([]byte, size) 86 | b.SetBytes(int64(size)) 87 | done := make(chan int, 1) 88 | 89 | go func() { 90 | newCh, err := server.Accept() 91 | if err != nil { 92 | b.Fatalf("Client: %v", err) 93 | } 94 | ch, incoming, err := newCh.Accept() 95 | go DiscardRequests(incoming) 96 | for i := 0; i < b.N; i++ { 97 | if _, err := io.ReadFull(ch, output); err != nil { 98 | b.Fatalf("ReadFull: %v", err) 99 | } 100 | } 101 | ch.Close() 102 | done <- 1 103 | }() 104 | 105 | ch, in, err := client.OpenChannel("speed", nil) 106 | if err != nil { 107 | b.Fatalf("OpenChannel: %v", err) 108 | } 109 | go DiscardRequests(in) 110 | 111 | b.ResetTimer() 112 | b.StartTimer() 113 | for i := 0; i < b.N; i++ { 114 | if _, err := ch.Write(input); err != nil { 115 | b.Fatalf("WriteFull: %v", err) 116 | } 117 | } 118 | ch.Close() 119 | b.StopTimer() 120 | 121 | <-done 122 | } 123 | -------------------------------------------------------------------------------- /tunnel/go.crypto/ssh/buffer.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package ssh 6 | 7 | import ( 8 | "io" 9 | "sync" 10 | ) 11 | 12 | // buffer provides a linked list buffer for data exchange 13 | // between producer and consumer. Theoretically the buffer is 14 | // of unlimited capacity as it does no allocation of its own. 15 | type buffer struct { 16 | // protects concurrent access to head, tail and closed 17 | *sync.Cond 18 | 19 | head *element // the buffer that will be read first 20 | tail *element // the buffer that will be read last 21 | 22 | closed bool 23 | } 24 | 25 | // An element represents a single link in a linked list. 26 | type element struct { 27 | buf []byte 28 | next *element 29 | } 30 | 31 | // newBuffer returns an empty buffer that is not closed. 32 | func newBuffer() *buffer { 33 | e := new(element) 34 | b := &buffer{ 35 | Cond: newCond(), 36 | head: e, 37 | tail: e, 38 | } 39 | return b 40 | } 41 | 42 | // write makes buf available for Read to receive. 43 | // buf must not be modified after the call to write. 44 | func (b *buffer) write(buf []byte) { 45 | b.Cond.L.Lock() 46 | e := &element{buf: buf} 47 | b.tail.next = e 48 | b.tail = e 49 | b.Cond.Signal() 50 | b.Cond.L.Unlock() 51 | } 52 | 53 | // eof closes the buffer. Reads from the buffer once all 54 | // the data has been consumed will receive os.EOF. 55 | func (b *buffer) eof() error { 56 | b.Cond.L.Lock() 57 | b.closed = true 58 | b.Cond.Signal() 59 | b.Cond.L.Unlock() 60 | return nil 61 | } 62 | 63 | // Read reads data from the internal buffer in buf. Reads will block 64 | // if no data is available, or until the buffer is closed. 65 | func (b *buffer) Read(buf []byte) (n int, err error) { 66 | b.Cond.L.Lock() 67 | defer b.Cond.L.Unlock() 68 | 69 | for len(buf) > 0 { 70 | // if there is data in b.head, copy it 71 | if len(b.head.buf) > 0 { 72 | r := copy(buf, b.head.buf) 73 | buf, b.head.buf = buf[r:], b.head.buf[r:] 74 | n += r 75 | continue 76 | } 77 | // if there is a next buffer, make it the head 78 | if len(b.head.buf) == 0 && b.head != b.tail { 79 | b.head = b.head.next 80 | continue 81 | } 82 | 83 | // if at least one byte has been copied, return 84 | if n > 0 { 85 | break 86 | } 87 | 88 | // if nothing was read, and there is nothing outstanding 89 | // check to see if the buffer is closed. 90 | if b.closed { 91 | err = io.EOF 92 | break 93 | } 94 | // out of buffers, wait for producer 95 | b.Cond.Wait() 96 | } 97 | return 98 | } 99 | -------------------------------------------------------------------------------- /tunnel/go.crypto/ssh/buffer_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package ssh 6 | 7 | import ( 8 | "io" 9 | "testing" 10 | ) 11 | 12 | var alphabet = []byte("abcdefghijklmnopqrstuvwxyz") 13 | 14 | func TestBufferReadwrite(t *testing.T) { 15 | b := newBuffer() 16 | b.write(alphabet[:10]) 17 | r, _ := b.Read(make([]byte, 10)) 18 | if r != 10 { 19 | t.Fatalf("Expected written == read == 10, written: 10, read %d", r) 20 | } 21 | 22 | b = newBuffer() 23 | b.write(alphabet[:5]) 24 | r, _ = b.Read(make([]byte, 10)) 25 | if r != 5 { 26 | t.Fatalf("Expected written == read == 5, written: 5, read %d", r) 27 | } 28 | 29 | b = newBuffer() 30 | b.write(alphabet[:10]) 31 | r, _ = b.Read(make([]byte, 5)) 32 | if r != 5 { 33 | t.Fatalf("Expected written == 10, read == 5, written: 10, read %d", r) 34 | } 35 | 36 | b = newBuffer() 37 | b.write(alphabet[:5]) 38 | b.write(alphabet[5:15]) 39 | r, _ = b.Read(make([]byte, 10)) 40 | r2, _ := b.Read(make([]byte, 10)) 41 | if r != 10 || r2 != 5 || 15 != r+r2 { 42 | t.Fatal("Expected written == read == 15") 43 | } 44 | } 45 | 46 | func TestBufferClose(t *testing.T) { 47 | b := newBuffer() 48 | b.write(alphabet[:10]) 49 | b.eof() 50 | _, err := b.Read(make([]byte, 5)) 51 | if err != nil { 52 | t.Fatal("expected read of 5 to not return EOF") 53 | } 54 | b = newBuffer() 55 | b.write(alphabet[:10]) 56 | b.eof() 57 | r, err := b.Read(make([]byte, 5)) 58 | r2, err2 := b.Read(make([]byte, 10)) 59 | if r != 5 || r2 != 5 || err != nil || err2 != nil { 60 | t.Fatal("expected reads of 5 and 5") 61 | } 62 | 63 | b = newBuffer() 64 | b.write(alphabet[:10]) 65 | b.eof() 66 | r, err = b.Read(make([]byte, 5)) 67 | r2, err2 = b.Read(make([]byte, 10)) 68 | r3, err3 := b.Read(make([]byte, 10)) 69 | if r != 5 || r2 != 5 || r3 != 0 || err != nil || err2 != nil || err3 != io.EOF { 70 | t.Fatal("expected reads of 5 and 5 and 0, with EOF") 71 | } 72 | 73 | b = newBuffer() 74 | b.write(make([]byte, 5)) 75 | b.write(make([]byte, 10)) 76 | b.eof() 77 | r, err = b.Read(make([]byte, 9)) 78 | r2, err2 = b.Read(make([]byte, 3)) 79 | r3, err3 = b.Read(make([]byte, 3)) 80 | r4, err4 := b.Read(make([]byte, 10)) 81 | if err != nil || err2 != nil || err3 != nil || err4 != io.EOF { 82 | t.Fatalf("Expected EOF on forth read only, err=%v, err2=%v, err3=%v, err4=%v", err, err2, err3, err4) 83 | } 84 | if r != 9 || r2 != 3 || r3 != 3 || r4 != 0 { 85 | t.Fatal("Expected written == read == 15", r, r2, r3, r4) 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /tunnel/go.crypto/ssh/cipher_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package ssh 6 | 7 | import ( 8 | "bytes" 9 | "crypto" 10 | "crypto/rand" 11 | "testing" 12 | ) 13 | 14 | func TestDefaultCiphersExist(t *testing.T) { 15 | for _, cipherAlgo := range supportedCiphers { 16 | if _, ok := cipherModes[cipherAlgo]; !ok { 17 | t.Errorf("default cipher %q is unknown", cipherAlgo) 18 | } 19 | } 20 | } 21 | 22 | func TestPacketCiphers(t *testing.T) { 23 | for cipher := range cipherModes { 24 | kr := &kexResult{Hash: crypto.SHA1} 25 | algs := directionAlgorithms{ 26 | Cipher: cipher, 27 | MAC: "hmac-sha1", 28 | Compression: "none", 29 | } 30 | client, err := newPacketCipher(clientKeys, algs, kr) 31 | if err != nil { 32 | t.Errorf("newPacketCipher(client, %q): %v", cipher, err) 33 | continue 34 | } 35 | server, err := newPacketCipher(clientKeys, algs, kr) 36 | if err != nil { 37 | t.Errorf("newPacketCipher(client, %q): %v", cipher, err) 38 | continue 39 | } 40 | 41 | want := "bla bla" 42 | input := []byte(want) 43 | buf := &bytes.Buffer{} 44 | if err := client.writePacket(0, buf, rand.Reader, input); err != nil { 45 | t.Errorf("writePacket(%q): %v", cipher, err) 46 | continue 47 | } 48 | 49 | packet, err := server.readPacket(0, buf) 50 | if err != nil { 51 | t.Errorf("readPacket(%q): %v", cipher, err) 52 | continue 53 | } 54 | 55 | if string(packet) != want { 56 | t.Errorf("roundtrip(%q): got %q, want %q", cipher, packet, want) 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /tunnel/go.crypto/ssh/client_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package ssh 6 | 7 | import ( 8 | "net" 9 | "testing" 10 | ) 11 | 12 | func testClientVersion(t *testing.T, config *ClientConfig, expected string) { 13 | clientConn, serverConn := net.Pipe() 14 | defer clientConn.Close() 15 | receivedVersion := make(chan string, 1) 16 | go func() { 17 | version, err := readVersion(serverConn) 18 | if err != nil { 19 | receivedVersion <- "" 20 | } else { 21 | receivedVersion <- string(version) 22 | } 23 | serverConn.Close() 24 | }() 25 | NewClientConn(clientConn, "", config) 26 | actual := <-receivedVersion 27 | if actual != expected { 28 | t.Fatalf("got %s; want %s", actual, expected) 29 | } 30 | } 31 | 32 | func TestCustomClientVersion(t *testing.T) { 33 | version := "Test-Client-Version-0.0" 34 | testClientVersion(t, &ClientConfig{ClientVersion: version}, version) 35 | } 36 | 37 | func TestDefaultClientVersion(t *testing.T) { 38 | testClientVersion(t, &ClientConfig{}, packageVersion) 39 | } 40 | -------------------------------------------------------------------------------- /tunnel/go.crypto/ssh/connection.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package ssh 6 | 7 | import ( 8 | "fmt" 9 | "net" 10 | ) 11 | 12 | // OpenChannelError is returned if the other side rejects an 13 | // OpenChannel request. 14 | type OpenChannelError struct { 15 | Reason RejectionReason 16 | Message string 17 | } 18 | 19 | func (e *OpenChannelError) Error() string { 20 | return fmt.Sprintf("ssh: rejected: %s (%s)", e.Reason, e.Message) 21 | } 22 | 23 | // ConnMetadata holds metadata for the connection. 24 | type ConnMetadata interface { 25 | // User returns the user ID for this connection. 26 | // It is empty if no authentication is used. 27 | User() string 28 | 29 | // SessionID returns the sesson hash, also denoted by H. 30 | SessionID() []byte 31 | 32 | // ClientVersion returns the client's version string as hashed 33 | // into the session ID. 34 | ClientVersion() []byte 35 | 36 | // ServerVersion returns the client's version string as hashed 37 | // into the session ID. 38 | ServerVersion() []byte 39 | 40 | // RemoteAddr returns the remote address for this connection. 41 | RemoteAddr() net.Addr 42 | 43 | // LocalAddr returns the local address for this connection. 44 | LocalAddr() net.Addr 45 | } 46 | 47 | // Conn represents an SSH connection for both server and client roles. 48 | // Conn is the basis for implementing an application layer, such 49 | // as ClientConn, which implements the traditional shell access for 50 | // clients. 51 | type Conn interface { 52 | ConnMetadata 53 | 54 | // SendRequest sends a global request, and returns the 55 | // reply. If wantReply is true, it returns the response status 56 | // and payload. See also RFC4254, section 4. 57 | SendRequest(name string, wantReply bool, payload []byte) (bool, []byte, error) 58 | 59 | // OpenChannel tries to open an channel. If the request is 60 | // rejected, it returns *OpenChannelError. On success it returns 61 | // the SSH Channel and a Go channel for incoming, out-of-band 62 | // requests. The Go channel must be serviced, or the 63 | // connection will hang. 64 | OpenChannel(name string, data []byte) (Channel, <-chan *Request, error) 65 | 66 | // Close closes the underlying network connection 67 | Close() error 68 | 69 | // Wait blocks until the connection has shut down, and returns the 70 | // error causing the shutdown. 71 | Wait() error 72 | 73 | // TODO(hanwen): consider exposing: 74 | // RequestKeyChange 75 | // Disconnect 76 | } 77 | 78 | // DiscardRequests consumes and rejects all requests from the 79 | // passed-in channel. 80 | func DiscardRequests(in <-chan *Request) { 81 | for req := range in { 82 | if req.WantReply { 83 | req.Reply(false, nil) 84 | } 85 | } 86 | } 87 | 88 | // A connection represents an incoming connection. 89 | type connection struct { 90 | transport *handshakeTransport 91 | sshConn 92 | 93 | // The connection protocol. 94 | *mux 95 | } 96 | 97 | func (c *connection) Close() error { 98 | return c.sshConn.conn.Close() 99 | } 100 | 101 | // sshconn provides net.Conn metadata, but disallows direct reads and 102 | // writes. 103 | type sshConn struct { 104 | conn net.Conn 105 | 106 | user string 107 | sessionID []byte 108 | clientVersion []byte 109 | serverVersion []byte 110 | } 111 | 112 | func dup(src []byte) []byte { 113 | dst := make([]byte, len(src)) 114 | copy(dst, src) 115 | return dst 116 | } 117 | 118 | func (c *sshConn) User() string { 119 | return c.user 120 | } 121 | 122 | func (c *sshConn) RemoteAddr() net.Addr { 123 | return c.conn.RemoteAddr() 124 | } 125 | 126 | func (c *sshConn) Close() error { 127 | return c.conn.Close() 128 | } 129 | 130 | func (c *sshConn) LocalAddr() net.Addr { 131 | return c.conn.LocalAddr() 132 | } 133 | 134 | func (c *sshConn) SessionID() []byte { 135 | return dup(c.sessionID) 136 | } 137 | 138 | func (c *sshConn) ClientVersion() []byte { 139 | return dup(c.clientVersion) 140 | } 141 | 142 | func (c *sshConn) ServerVersion() []byte { 143 | return dup(c.serverVersion) 144 | } 145 | -------------------------------------------------------------------------------- /tunnel/go.crypto/ssh/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | /* 6 | Package ssh implements an SSH client and server. 7 | 8 | SSH is a transport security protocol, an authentication protocol and a 9 | family of application protocols. The most typical application level 10 | protocol is a remote shell and this is specifically implemented. However, 11 | the multiplexed nature of SSH is exposed to users that wish to support 12 | others. 13 | 14 | References: 15 | [PROTOCOL.certkeys]: http://www.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL.certkeys 16 | [SSH-PARAMETERS]: http://www.iana.org/assignments/ssh-parameters/ssh-parameters.xml#ssh-parameters-1 17 | */ 18 | package ssh 19 | -------------------------------------------------------------------------------- /tunnel/go.crypto/ssh/kex_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package ssh 6 | 7 | // Key exchange tests. 8 | 9 | import ( 10 | "crypto/rand" 11 | "reflect" 12 | "testing" 13 | ) 14 | 15 | func TestKexes(t *testing.T) { 16 | type kexResultErr struct { 17 | result *kexResult 18 | err error 19 | } 20 | 21 | for name, kex := range kexAlgoMap { 22 | a, b := memPipe() 23 | 24 | s := make(chan kexResultErr, 1) 25 | c := make(chan kexResultErr, 1) 26 | var magics handshakeMagics 27 | go func() { 28 | r, e := kex.Client(a, rand.Reader, &magics) 29 | c <- kexResultErr{r, e} 30 | }() 31 | go func() { 32 | r, e := kex.Server(b, rand.Reader, &magics, testSigners["ecdsa"]) 33 | s <- kexResultErr{r, e} 34 | }() 35 | 36 | clientRes := <-c 37 | serverRes := <-s 38 | if clientRes.err != nil { 39 | t.Errorf("client: %v", clientRes.err) 40 | } 41 | if serverRes.err != nil { 42 | t.Errorf("server: %v", serverRes.err) 43 | } 44 | if !reflect.DeepEqual(clientRes.result, serverRes.result) { 45 | t.Errorf("kex %q: mismatch %#v, %#v", name, clientRes.result, serverRes.result) 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /tunnel/go.crypto/ssh/mac.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package ssh 6 | 7 | // Message authentication support 8 | 9 | import ( 10 | "crypto/hmac" 11 | "crypto/sha1" 12 | "hash" 13 | ) 14 | 15 | type macMode struct { 16 | keySize int 17 | new func(key []byte) hash.Hash 18 | } 19 | 20 | // truncatingMAC wraps around a hash.Hash and truncates the output digest to 21 | // a given size. 22 | type truncatingMAC struct { 23 | length int 24 | hmac hash.Hash 25 | } 26 | 27 | func (t truncatingMAC) Write(data []byte) (int, error) { 28 | return t.hmac.Write(data) 29 | } 30 | 31 | func (t truncatingMAC) Sum(in []byte) []byte { 32 | out := t.hmac.Sum(in) 33 | return out[:len(in)+t.length] 34 | } 35 | 36 | func (t truncatingMAC) Reset() { 37 | t.hmac.Reset() 38 | } 39 | 40 | func (t truncatingMAC) Size() int { 41 | return t.length 42 | } 43 | 44 | func (t truncatingMAC) BlockSize() int { return t.hmac.BlockSize() } 45 | 46 | var macModes = map[string]*macMode{ 47 | "hmac-sha1": {20, func(key []byte) hash.Hash { 48 | return hmac.New(sha1.New, key) 49 | }}, 50 | "hmac-sha1-96": {20, func(key []byte) hash.Hash { 51 | return truncatingMAC{12, hmac.New(sha1.New, key)} 52 | }}, 53 | } 54 | -------------------------------------------------------------------------------- /tunnel/go.crypto/ssh/mempipe_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package ssh 6 | 7 | import ( 8 | "io" 9 | "sync" 10 | "testing" 11 | ) 12 | 13 | // An in-memory packetConn. It is safe to call Close and writePacket 14 | // from different goroutines. 15 | type memTransport struct { 16 | eof bool 17 | pending [][]byte 18 | write *memTransport 19 | sync.Mutex 20 | *sync.Cond 21 | } 22 | 23 | func (t *memTransport) readPacket() ([]byte, error) { 24 | t.Lock() 25 | defer t.Unlock() 26 | for { 27 | if len(t.pending) > 0 { 28 | r := t.pending[0] 29 | t.pending = t.pending[1:] 30 | return r, nil 31 | } 32 | if t.eof { 33 | return nil, io.EOF 34 | } 35 | t.Cond.Wait() 36 | } 37 | } 38 | 39 | func (t *memTransport) closeSelf() error { 40 | t.Lock() 41 | defer t.Unlock() 42 | if t.eof { 43 | return io.EOF 44 | } 45 | t.eof = true 46 | t.Cond.Broadcast() 47 | return nil 48 | } 49 | 50 | func (t *memTransport) Close() error { 51 | err := t.write.closeSelf() 52 | t.closeSelf() 53 | return err 54 | } 55 | 56 | func (t *memTransport) writePacket(p []byte) error { 57 | t.write.Lock() 58 | defer t.write.Unlock() 59 | if t.write.eof { 60 | return io.EOF 61 | } 62 | t.write.pending = append(t.write.pending, p) 63 | t.write.Cond.Signal() 64 | return nil 65 | } 66 | 67 | func memPipe() (a, b packetConn) { 68 | t1 := memTransport{} 69 | t2 := memTransport{} 70 | t1.write = &t2 71 | t2.write = &t1 72 | t1.Cond = sync.NewCond(&t1.Mutex) 73 | t2.Cond = sync.NewCond(&t2.Mutex) 74 | return &t1, &t2 75 | } 76 | 77 | func TestmemPipe(t *testing.T) { 78 | a, b := memPipe() 79 | if err := a.writePacket([]byte{42}); err != nil { 80 | t.Fatalf("writePacket: %v", err) 81 | } 82 | if err := a.Close(); err != nil { 83 | t.Fatal("Close: ", err) 84 | } 85 | p, err := b.readPacket() 86 | if err != nil { 87 | t.Fatal("readPacket: ", err) 88 | } 89 | if len(p) != 1 || p[0] != 42 { 90 | t.Fatalf("got %v, want {42}", p) 91 | } 92 | p, err = b.readPacket() 93 | if err != io.EOF { 94 | t.Fatalf("got %v, %v, want EOF", p, err) 95 | } 96 | } 97 | 98 | func TestDoubleClose(t *testing.T) { 99 | a, _ := memPipe() 100 | err := a.Close() 101 | if err != nil { 102 | t.Errorf("Close: %v", err) 103 | } 104 | err = a.Close() 105 | if err != io.EOF { 106 | t.Errorf("expect EOF on double close.") 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /tunnel/go.crypto/ssh/tcpip_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package ssh 6 | 7 | import ( 8 | "testing" 9 | ) 10 | 11 | func TestAutoPortListenBroken(t *testing.T) { 12 | broken := "SSH-2.0-OpenSSH_5.9hh11" 13 | works := "SSH-2.0-OpenSSH_6.1" 14 | if !isBrokenOpenSSHVersion(broken) { 15 | t.Errorf("version %q not marked as broken", broken) 16 | } 17 | if isBrokenOpenSSHVersion(works) { 18 | t.Errorf("version %q marked as broken", works) 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /tunnel/go.crypto/ssh/terminal/util_bsd.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build darwin dragonfly freebsd netbsd openbsd 6 | 7 | package terminal 8 | 9 | import "syscall" 10 | 11 | const ioctlReadTermios = syscall.TIOCGETA 12 | const ioctlWriteTermios = syscall.TIOCSETA 13 | -------------------------------------------------------------------------------- /tunnel/go.crypto/ssh/terminal/util_linux.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package terminal 6 | 7 | // These constants are declared here, rather than importing 8 | // them from the syscall package as some syscall packages, even 9 | // on linux, for example gccgo, do not declare them. 10 | const ioctlReadTermios = 0x5401 // syscall.TCGETS 11 | const ioctlWriteTermios = 0x5402 // syscall.TCSETS 12 | -------------------------------------------------------------------------------- /tunnel/go.crypto/ssh/test/agent_unix_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build darwin dragonfly freebsd linux netbsd openbsd 6 | 7 | package test 8 | 9 | import ( 10 | "bytes" 11 | "testing" 12 | 13 | "golang.org/x/crypto/ssh" 14 | "golang.org/x/crypto/ssh/agent" 15 | ) 16 | 17 | func TestAgentForward(t *testing.T) { 18 | server := newServer(t) 19 | defer server.Shutdown() 20 | conn := server.Dial(clientConfig()) 21 | defer conn.Close() 22 | 23 | keyring := agent.NewKeyring() 24 | keyring.Add(testPrivateKeys["dsa"], nil, "") 25 | pub := testPublicKeys["dsa"] 26 | 27 | sess, err := conn.NewSession() 28 | if err != nil { 29 | t.Fatalf("NewSession: %v", err) 30 | } 31 | if err := agent.RequestAgentForwarding(sess); err != nil { 32 | t.Fatalf("RequestAgentForwarding: %v", err) 33 | } 34 | 35 | if err := agent.ForwardToAgent(conn, keyring); err != nil { 36 | t.Fatalf("SetupForwardKeyring: %v", err) 37 | } 38 | out, err := sess.CombinedOutput("ssh-add -L") 39 | if err != nil { 40 | t.Fatalf("running ssh-add: %v, out %s", err, out) 41 | } 42 | key, _, _, _, err := ssh.ParseAuthorizedKey(out) 43 | if err != nil { 44 | t.Fatalf("ParseAuthorizedKey(%q): %v", out, err) 45 | } 46 | 47 | if !bytes.Equal(key.Marshal(), pub.Marshal()) { 48 | t.Fatalf("got key %s, want %s", ssh.MarshalAuthorizedKey(key), ssh.MarshalAuthorizedKey(pub)) 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /tunnel/go.crypto/ssh/test/cert_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build darwin dragonfly freebsd linux netbsd openbsd 6 | 7 | package test 8 | 9 | import ( 10 | "crypto/rand" 11 | "testing" 12 | 13 | "golang.org/x/crypto/ssh" 14 | ) 15 | 16 | func TestCertLogin(t *testing.T) { 17 | s := newServer(t) 18 | defer s.Shutdown() 19 | 20 | // Use a key different from the default. 21 | clientKey := testSigners["dsa"] 22 | caAuthKey := testSigners["ecdsa"] 23 | cert := &ssh.Certificate{ 24 | Key: clientKey.PublicKey(), 25 | ValidPrincipals: []string{username()}, 26 | CertType: ssh.UserCert, 27 | ValidBefore: ssh.CertTimeInfinity, 28 | } 29 | if err := cert.SignCert(rand.Reader, caAuthKey); err != nil { 30 | t.Fatalf("SetSignature: %v", err) 31 | } 32 | 33 | certSigner, err := ssh.NewCertSigner(cert, clientKey) 34 | if err != nil { 35 | t.Fatalf("NewCertSigner: %v", err) 36 | } 37 | 38 | conf := &ssh.ClientConfig{ 39 | User: username(), 40 | } 41 | conf.Auth = append(conf.Auth, ssh.PublicKeys(certSigner)) 42 | client, err := s.TryDial(conf) 43 | if err != nil { 44 | t.Fatalf("TryDial: %v", err) 45 | } 46 | client.Close() 47 | } 48 | -------------------------------------------------------------------------------- /tunnel/go.crypto/ssh/test/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // This package contains integration tests for the 6 | // code.google.com/p/go.crypto/ssh package. 7 | package test 8 | -------------------------------------------------------------------------------- /tunnel/go.crypto/ssh/test/forward_unix_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build darwin dragonfly freebsd linux netbsd openbsd 6 | 7 | package test 8 | 9 | import ( 10 | "bytes" 11 | "io" 12 | "io/ioutil" 13 | "math/rand" 14 | "net" 15 | "testing" 16 | "time" 17 | ) 18 | 19 | func TestPortForward(t *testing.T) { 20 | server := newServer(t) 21 | defer server.Shutdown() 22 | conn := server.Dial(clientConfig()) 23 | defer conn.Close() 24 | 25 | sshListener, err := conn.Listen("tcp", "localhost:0") 26 | if err != nil { 27 | t.Fatal(err) 28 | } 29 | 30 | go func() { 31 | sshConn, err := sshListener.Accept() 32 | if err != nil { 33 | t.Fatalf("listen.Accept failed: %v", err) 34 | } 35 | 36 | _, err = io.Copy(sshConn, sshConn) 37 | if err != nil && err != io.EOF { 38 | t.Fatalf("ssh client copy: %v", err) 39 | } 40 | sshConn.Close() 41 | }() 42 | 43 | forwardedAddr := sshListener.Addr().String() 44 | tcpConn, err := net.Dial("tcp", forwardedAddr) 45 | if err != nil { 46 | t.Fatalf("TCP dial failed: %v", err) 47 | } 48 | 49 | readChan := make(chan []byte) 50 | go func() { 51 | data, _ := ioutil.ReadAll(tcpConn) 52 | readChan <- data 53 | }() 54 | 55 | // Invent some data. 56 | data := make([]byte, 100*1000) 57 | for i := range data { 58 | data[i] = byte(i % 255) 59 | } 60 | 61 | var sent []byte 62 | for len(sent) < 1000*1000 { 63 | // Send random sized chunks 64 | m := rand.Intn(len(data)) 65 | n, err := tcpConn.Write(data[:m]) 66 | if err != nil { 67 | break 68 | } 69 | sent = append(sent, data[:n]...) 70 | } 71 | if err := tcpConn.(*net.TCPConn).CloseWrite(); err != nil { 72 | t.Errorf("tcpConn.CloseWrite: %v", err) 73 | } 74 | 75 | read := <-readChan 76 | 77 | if len(sent) != len(read) { 78 | t.Fatalf("got %d bytes, want %d", len(read), len(sent)) 79 | } 80 | if bytes.Compare(sent, read) != 0 { 81 | t.Fatalf("read back data does not match") 82 | } 83 | 84 | if err := sshListener.Close(); err != nil { 85 | t.Fatalf("sshListener.Close: %v", err) 86 | } 87 | 88 | // Check that the forward disappeared. 89 | tcpConn, err = net.Dial("tcp", forwardedAddr) 90 | if err == nil { 91 | tcpConn.Close() 92 | t.Errorf("still listening to %s after closing", forwardedAddr) 93 | } 94 | } 95 | 96 | func TestAcceptClose(t *testing.T) { 97 | server := newServer(t) 98 | defer server.Shutdown() 99 | conn := server.Dial(clientConfig()) 100 | 101 | sshListener, err := conn.Listen("tcp", "localhost:0") 102 | if err != nil { 103 | t.Fatal(err) 104 | } 105 | 106 | quit := make(chan error, 1) 107 | go func() { 108 | for { 109 | c, err := sshListener.Accept() 110 | if err != nil { 111 | quit <- err 112 | break 113 | } 114 | c.Close() 115 | } 116 | }() 117 | sshListener.Close() 118 | 119 | select { 120 | case <-time.After(1 * time.Second): 121 | t.Errorf("timeout: listener did not close.") 122 | case err := <-quit: 123 | t.Logf("quit as expected (error %v)", err) 124 | } 125 | } 126 | 127 | // Check that listeners exit if the underlying client transport dies. 128 | func TestPortForwardConnectionClose(t *testing.T) { 129 | server := newServer(t) 130 | defer server.Shutdown() 131 | conn := server.Dial(clientConfig()) 132 | 133 | sshListener, err := conn.Listen("tcp", "localhost:0") 134 | if err != nil { 135 | t.Fatal(err) 136 | } 137 | 138 | quit := make(chan error, 1) 139 | go func() { 140 | for { 141 | c, err := sshListener.Accept() 142 | if err != nil { 143 | quit <- err 144 | break 145 | } 146 | c.Close() 147 | } 148 | }() 149 | 150 | // It would be even nicer if we closed the server side, but it 151 | // is more involved as the fd for that side is dup()ed. 152 | server.clientConn.Close() 153 | 154 | select { 155 | case <-time.After(1 * time.Second): 156 | t.Errorf("timeout: listener did not close.") 157 | case err := <-quit: 158 | t.Logf("quit as expected (error %v)", err) 159 | } 160 | } 161 | -------------------------------------------------------------------------------- /tunnel/go.crypto/ssh/test/tcpip_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build !windows 6 | 7 | package test 8 | 9 | // direct-tcpip functional tests 10 | 11 | import ( 12 | "io" 13 | "net" 14 | "testing" 15 | ) 16 | 17 | func TestDial(t *testing.T) { 18 | server := newServer(t) 19 | defer server.Shutdown() 20 | sshConn := server.Dial(clientConfig()) 21 | defer sshConn.Close() 22 | 23 | l, err := net.Listen("tcp", "127.0.0.1:0") 24 | if err != nil { 25 | t.Fatalf("Listen: %v", err) 26 | } 27 | defer l.Close() 28 | 29 | go func() { 30 | for { 31 | c, err := l.Accept() 32 | if err != nil { 33 | break 34 | } 35 | 36 | io.WriteString(c, c.RemoteAddr().String()) 37 | c.Close() 38 | } 39 | }() 40 | 41 | conn, err := sshConn.Dial("tcp", l.Addr().String()) 42 | if err != nil { 43 | t.Fatalf("Dial: %v", err) 44 | } 45 | defer conn.Close() 46 | } 47 | -------------------------------------------------------------------------------- /tunnel/go.crypto/ssh/test/testdata_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // IMPLEMENTOR NOTE: To avoid a package loop, this file is in three places: 6 | // ssh/, ssh/agent, and ssh/test/. It should be kept in sync across all three 7 | // instances. 8 | 9 | package test 10 | 11 | import ( 12 | "crypto/rand" 13 | "fmt" 14 | 15 | "golang.org/x/crypto/ssh" 16 | "golang.org/x/crypto/ssh/testdata" 17 | ) 18 | 19 | var ( 20 | testPrivateKeys map[string]interface{} 21 | testSigners map[string]ssh.Signer 22 | testPublicKeys map[string]ssh.PublicKey 23 | ) 24 | 25 | func init() { 26 | var err error 27 | 28 | n := len(testdata.PEMBytes) 29 | testPrivateKeys = make(map[string]interface{}, n) 30 | testSigners = make(map[string]ssh.Signer, n) 31 | testPublicKeys = make(map[string]ssh.PublicKey, n) 32 | for t, k := range testdata.PEMBytes { 33 | testPrivateKeys[t], err = ssh.ParseRawPrivateKey(k) 34 | if err != nil { 35 | panic(fmt.Sprintf("Unable to parse test key %s: %v", t, err)) 36 | } 37 | testSigners[t], err = ssh.NewSignerFromKey(testPrivateKeys[t]) 38 | if err != nil { 39 | panic(fmt.Sprintf("Unable to create signer for test key %s: %v", t, err)) 40 | } 41 | testPublicKeys[t] = testSigners[t].PublicKey() 42 | } 43 | 44 | // Create a cert and sign it for use in tests. 45 | testCert := &ssh.Certificate{ 46 | Nonce: []byte{}, // To pass reflect.DeepEqual after marshal & parse, this must be non-nil 47 | ValidPrincipals: []string{"gopher1", "gopher2"}, // increases test coverage 48 | ValidAfter: 0, // unix epoch 49 | ValidBefore: ssh.CertTimeInfinity, // The end of currently representable time. 50 | Reserved: []byte{}, // To pass reflect.DeepEqual after marshal & parse, this must be non-nil 51 | Key: testPublicKeys["ecdsa"], 52 | SignatureKey: testPublicKeys["rsa"], 53 | Permissions: ssh.Permissions{ 54 | CriticalOptions: map[string]string{}, 55 | Extensions: map[string]string{}, 56 | }, 57 | } 58 | testCert.SignCert(rand.Reader, testSigners["rsa"]) 59 | testPrivateKeys["cert"] = testPrivateKeys["ecdsa"] 60 | testSigners["cert"], err = ssh.NewCertSigner(testCert, testSigners["ecdsa"]) 61 | if err != nil { 62 | panic(fmt.Sprintf("Unable to create certificate signer: %v", err)) 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /tunnel/go.crypto/ssh/testdata/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // This package contains test data shared between the various subpackages of 6 | // the code.google.com/p/go.crypto/ssh package. Under no circumstance should 7 | // this data be used for production code. 8 | package testdata 9 | -------------------------------------------------------------------------------- /tunnel/go.crypto/ssh/testdata/keys.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package testdata 6 | 7 | var PEMBytes = map[string][]byte{ 8 | "dsa": []byte(`-----BEGIN DSA PRIVATE KEY----- 9 | MIIBuwIBAAKBgQD6PDSEyXiI9jfNs97WuM46MSDCYlOqWw80ajN16AohtBncs1YB 10 | lHk//dQOvCYOsYaE+gNix2jtoRjwXhDsc25/IqQbU1ahb7mB8/rsaILRGIbA5WH3 11 | EgFtJmXFovDz3if6F6TzvhFpHgJRmLYVR8cqsezL3hEZOvvs2iH7MorkxwIVAJHD 12 | nD82+lxh2fb4PMsIiaXudAsBAoGAQRf7Q/iaPRn43ZquUhd6WwvirqUj+tkIu6eV 13 | 2nZWYmXLlqFQKEy4Tejl7Wkyzr2OSYvbXLzo7TNxLKoWor6ips0phYPPMyXld14r 14 | juhT24CrhOzuLMhDduMDi032wDIZG4Y+K7ElU8Oufn8Sj5Wge8r6ANmmVgmFfynr 15 | FhdYCngCgYEA3ucGJ93/Mx4q4eKRDxcWD3QzWyqpbRVRRV1Vmih9Ha/qC994nJFz 16 | DQIdjxDIT2Rk2AGzMqFEB68Zc3O+Wcsmz5eWWzEwFxaTwOGWTyDqsDRLm3fD+QYj 17 | nOwuxb0Kce+gWI8voWcqC9cyRm09jGzu2Ab3Bhtpg8JJ8L7gS3MRZK4CFEx4UAfY 18 | Fmsr0W6fHB9nhS4/UXM8 19 | -----END DSA PRIVATE KEY----- 20 | `), 21 | "ecdsa": []byte(`-----BEGIN EC PRIVATE KEY----- 22 | MHcCAQEEINGWx0zo6fhJ/0EAfrPzVFyFC9s18lBt3cRoEDhS3ARooAoGCCqGSM49 23 | AwEHoUQDQgAEi9Hdw6KvZcWxfg2IDhA7UkpDtzzt6ZqJXSsFdLd+Kx4S3Sx4cVO+ 24 | 6/ZOXRnPmNAlLUqjShUsUBBngG0u2fqEqA== 25 | -----END EC PRIVATE KEY----- 26 | `), 27 | "rsa": []byte(`-----BEGIN RSA PRIVATE KEY----- 28 | MIIBOwIBAAJBALdGZxkXDAjsYk10ihwU6Id2KeILz1TAJuoq4tOgDWxEEGeTrcld 29 | r/ZwVaFzjWzxaf6zQIJbfaSEAhqD5yo72+sCAwEAAQJBAK8PEVU23Wj8mV0QjwcJ 30 | tZ4GcTUYQL7cF4+ezTCE9a1NrGnCP2RuQkHEKxuTVrxXt+6OF15/1/fuXnxKjmJC 31 | nxkCIQDaXvPPBi0c7vAxGwNY9726x01/dNbHCE0CBtcotobxpwIhANbbQbh3JHVW 32 | 2haQh4fAG5mhesZKAGcxTyv4mQ7uMSQdAiAj+4dzMpJWdSzQ+qGHlHMIBvVHLkqB 33 | y2VdEyF7DPCZewIhAI7GOI/6LDIFOvtPo6Bj2nNmyQ1HU6k/LRtNIXi4c9NJAiAr 34 | rrxx26itVhJmcvoUhOjwuzSlP2bE5VHAvkGB352YBg== 35 | -----END RSA PRIVATE KEY----- 36 | `), 37 | "user": []byte(`-----BEGIN EC PRIVATE KEY----- 38 | MHcCAQEEILYCAeq8f7V4vSSypRw7pxy8yz3V5W4qg8kSC3zJhqpQoAoGCCqGSM49 39 | AwEHoUQDQgAEYcO2xNKiRUYOLEHM7VYAp57HNyKbOdYtHD83Z4hzNPVC4tM5mdGD 40 | PLL8IEwvYu2wq+lpXfGQnNMbzYf9gspG0w== 41 | -----END EC PRIVATE KEY----- 42 | `), 43 | } 44 | -------------------------------------------------------------------------------- /tunnel/go.crypto/ssh/testdata_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // IMPLEMENTOR NOTE: To avoid a package loop, this file is in three places: 6 | // ssh/, ssh/agent, and ssh/test/. It should be kept in sync across all three 7 | // instances. 8 | 9 | package ssh 10 | 11 | import ( 12 | "crypto/rand" 13 | "fmt" 14 | 15 | "golang.org/x/crypto/ssh/testdata" 16 | ) 17 | 18 | var ( 19 | testPrivateKeys map[string]interface{} 20 | testSigners map[string]Signer 21 | testPublicKeys map[string]PublicKey 22 | ) 23 | 24 | func init() { 25 | var err error 26 | 27 | n := len(testdata.PEMBytes) 28 | testPrivateKeys = make(map[string]interface{}, n) 29 | testSigners = make(map[string]Signer, n) 30 | testPublicKeys = make(map[string]PublicKey, n) 31 | for t, k := range testdata.PEMBytes { 32 | testPrivateKeys[t], err = ParseRawPrivateKey(k) 33 | if err != nil { 34 | panic(fmt.Sprintf("Unable to parse test key %s: %v", t, err)) 35 | } 36 | testSigners[t], err = NewSignerFromKey(testPrivateKeys[t]) 37 | if err != nil { 38 | panic(fmt.Sprintf("Unable to create signer for test key %s: %v", t, err)) 39 | } 40 | testPublicKeys[t] = testSigners[t].PublicKey() 41 | } 42 | 43 | // Create a cert and sign it for use in tests. 44 | testCert := &Certificate{ 45 | Nonce: []byte{}, // To pass reflect.DeepEqual after marshal & parse, this must be non-nil 46 | ValidPrincipals: []string{"gopher1", "gopher2"}, // increases test coverage 47 | ValidAfter: 0, // unix epoch 48 | ValidBefore: CertTimeInfinity, // The end of currently representable time. 49 | Reserved: []byte{}, // To pass reflect.DeepEqual after marshal & parse, this must be non-nil 50 | Key: testPublicKeys["ecdsa"], 51 | SignatureKey: testPublicKeys["rsa"], 52 | Permissions: Permissions{ 53 | CriticalOptions: map[string]string{}, 54 | Extensions: map[string]string{}, 55 | }, 56 | } 57 | testCert.SignCert(rand.Reader, testSigners["rsa"]) 58 | testPrivateKeys["cert"] = testPrivateKeys["ecdsa"] 59 | testSigners["cert"], err = NewCertSigner(testCert, testSigners["ecdsa"]) 60 | if err != nil { 61 | panic(fmt.Sprintf("Unable to create certificate signer: %v", err)) 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /tunnel/go.crypto/ssh/transport_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package ssh 6 | 7 | import ( 8 | "bytes" 9 | "crypto/rand" 10 | "encoding/binary" 11 | "strings" 12 | "testing" 13 | ) 14 | 15 | func TestReadVersion(t *testing.T) { 16 | longversion := strings.Repeat("SSH-2.0-bla", 50)[:253] 17 | cases := map[string]string{ 18 | "SSH-2.0-bla\r\n": "SSH-2.0-bla", 19 | "SSH-2.0-bla\n": "SSH-2.0-bla", 20 | longversion + "\r\n": longversion, 21 | } 22 | 23 | for in, want := range cases { 24 | result, err := readVersion(bytes.NewBufferString(in)) 25 | if err != nil { 26 | t.Errorf("readVersion(%q): %s", in, err) 27 | } 28 | got := string(result) 29 | if got != want { 30 | t.Errorf("got %q, want %q", got, want) 31 | } 32 | } 33 | } 34 | 35 | func TestReadVersionError(t *testing.T) { 36 | longversion := strings.Repeat("SSH-2.0-bla", 50)[:253] 37 | cases := []string{ 38 | longversion + "too-long\r\n", 39 | } 40 | for _, in := range cases { 41 | if _, err := readVersion(bytes.NewBufferString(in)); err == nil { 42 | t.Errorf("readVersion(%q) should have failed", in) 43 | } 44 | } 45 | } 46 | 47 | func TestExchangeVersionsBasic(t *testing.T) { 48 | v := "SSH-2.0-bla" 49 | buf := bytes.NewBufferString(v + "\r\n") 50 | them, err := exchangeVersions(buf, []byte("xyz")) 51 | if err != nil { 52 | t.Errorf("exchangeVersions: %v", err) 53 | } 54 | 55 | if want := "SSH-2.0-bla"; string(them) != want { 56 | t.Errorf("got %q want %q for our version", them, want) 57 | } 58 | } 59 | 60 | func TestExchangeVersions(t *testing.T) { 61 | cases := []string{ 62 | "not\x000allowed", 63 | "not allowed\n", 64 | } 65 | for _, c := range cases { 66 | buf := bytes.NewBufferString("SSH-2.0-bla\r\n") 67 | if _, err := exchangeVersions(buf, []byte(c)); err == nil { 68 | t.Errorf("exchangeVersions(%q): should have failed", c) 69 | } 70 | } 71 | } 72 | 73 | type closerBuffer struct { 74 | bytes.Buffer 75 | } 76 | 77 | func (b *closerBuffer) Close() error { 78 | return nil 79 | } 80 | 81 | func TestTransportMaxPacketWrite(t *testing.T) { 82 | buf := &closerBuffer{} 83 | tr := newTransport(buf, rand.Reader, true) 84 | huge := make([]byte, maxPacket+1) 85 | err := tr.writePacket(huge) 86 | if err == nil { 87 | t.Errorf("transport accepted write for a huge packet.") 88 | } 89 | } 90 | 91 | func TestTransportMaxPacketReader(t *testing.T) { 92 | var header [5]byte 93 | huge := make([]byte, maxPacket+128) 94 | binary.BigEndian.PutUint32(header[0:], uint32(len(huge))) 95 | // padding. 96 | header[4] = 0 97 | 98 | buf := &closerBuffer{} 99 | buf.Write(header[:]) 100 | buf.Write(huge) 101 | 102 | tr := newTransport(buf, rand.Reader, true) 103 | _, err := tr.readPacket() 104 | if err == nil { 105 | t.Errorf("transport succeeded reading huge packet.") 106 | } else if !strings.Contains(err.Error(), "large") { 107 | t.Errorf("got %q, should mention %q", err.Error(), "large") 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /tunnel/go.crypto/xtea/block.go: -------------------------------------------------------------------------------- 1 | // Copyright 2009 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | /* 6 | Implementation adapted from Needham and Wheeler's paper: 7 | http://www.cix.co.uk/~klockstone/xtea.pdf 8 | 9 | A precalculated look up table is used during encryption/decryption for values that are based purely on the key. 10 | */ 11 | 12 | package xtea 13 | 14 | // XTEA is based on 64 rounds. 15 | const numRounds = 64 16 | 17 | // blockToUint32 reads an 8 byte slice into two uint32s. 18 | // The block is treated as big endian. 19 | func blockToUint32(src []byte) (uint32, uint32) { 20 | r0 := uint32(src[0])<<24 | uint32(src[1])<<16 | uint32(src[2])<<8 | uint32(src[3]) 21 | r1 := uint32(src[4])<<24 | uint32(src[5])<<16 | uint32(src[6])<<8 | uint32(src[7]) 22 | return r0, r1 23 | } 24 | 25 | // uint32ToBlock writes two uint32s into an 8 byte data block. 26 | // Values are written as big endian. 27 | func uint32ToBlock(v0, v1 uint32, dst []byte) { 28 | dst[0] = byte(v0 >> 24) 29 | dst[1] = byte(v0 >> 16) 30 | dst[2] = byte(v0 >> 8) 31 | dst[3] = byte(v0) 32 | dst[4] = byte(v1 >> 24) 33 | dst[5] = byte(v1 >> 16) 34 | dst[6] = byte(v1 >> 8) 35 | dst[7] = byte(v1 >> 0) 36 | } 37 | 38 | // encryptBlock encrypts a single 8 byte block using XTEA. 39 | func encryptBlock(c *Cipher, dst, src []byte) { 40 | v0, v1 := blockToUint32(src) 41 | 42 | // Two rounds of XTEA applied per loop 43 | for i := 0; i < numRounds; { 44 | v0 += ((v1<<4 ^ v1>>5) + v1) ^ c.table[i] 45 | i++ 46 | v1 += ((v0<<4 ^ v0>>5) + v0) ^ c.table[i] 47 | i++ 48 | } 49 | 50 | uint32ToBlock(v0, v1, dst) 51 | } 52 | 53 | // decryptBlock decrypt a single 8 byte block using XTEA. 54 | func decryptBlock(c *Cipher, dst, src []byte) { 55 | v0, v1 := blockToUint32(src) 56 | 57 | // Two rounds of XTEA applied per loop 58 | for i := numRounds; i > 0; { 59 | i-- 60 | v1 -= ((v0<<4 ^ v0>>5) + v0) ^ c.table[i] 61 | i-- 62 | v0 -= ((v1<<4 ^ v1>>5) + v1) ^ c.table[i] 63 | } 64 | 65 | uint32ToBlock(v0, v1, dst) 66 | } 67 | -------------------------------------------------------------------------------- /tunnel/go.crypto/xtea/cipher.go: -------------------------------------------------------------------------------- 1 | // Copyright 2009 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package xtea implements XTEA encryption, as defined in Needham and Wheeler's 6 | // 1997 technical report, "Tea extensions." 7 | package xtea 8 | 9 | // For details, see http://www.cix.co.uk/~klockstone/xtea.pdf 10 | 11 | import "strconv" 12 | 13 | // The XTEA block size in bytes. 14 | const BlockSize = 8 15 | 16 | // A Cipher is an instance of an XTEA cipher using a particular key. 17 | // table contains a series of precalculated values that are used each round. 18 | type Cipher struct { 19 | table [64]uint32 20 | } 21 | 22 | type KeySizeError int 23 | 24 | func (k KeySizeError) Error() string { 25 | return "crypto/xtea: invalid key size " + strconv.Itoa(int(k)) 26 | } 27 | 28 | // NewCipher creates and returns a new Cipher. 29 | // The key argument should be the XTEA key. 30 | // XTEA only supports 128 bit (16 byte) keys. 31 | func NewCipher(key []byte) (*Cipher, error) { 32 | k := len(key) 33 | switch k { 34 | default: 35 | return nil, KeySizeError(k) 36 | case 16: 37 | break 38 | } 39 | 40 | c := new(Cipher) 41 | initCipher(c, key) 42 | 43 | return c, nil 44 | } 45 | 46 | // BlockSize returns the XTEA block size, 8 bytes. 47 | // It is necessary to satisfy the Block interface in the 48 | // package "crypto/cipher". 49 | func (c *Cipher) BlockSize() int { return BlockSize } 50 | 51 | // Encrypt encrypts the 8 byte buffer src using the key and stores the result in dst. 52 | // Note that for amounts of data larger than a block, 53 | // it is not safe to just call Encrypt on successive blocks; 54 | // instead, use an encryption mode like CBC (see crypto/cipher/cbc.go). 55 | func (c *Cipher) Encrypt(dst, src []byte) { encryptBlock(c, dst, src) } 56 | 57 | // Decrypt decrypts the 8 byte buffer src using the key k and stores the result in dst. 58 | func (c *Cipher) Decrypt(dst, src []byte) { decryptBlock(c, dst, src) } 59 | 60 | // initCipher initializes the cipher context by creating a look up table 61 | // of precalculated values that are based on the key. 62 | func initCipher(c *Cipher, key []byte) { 63 | // Load the key into four uint32s 64 | var k [4]uint32 65 | for i := 0; i < len(k); i++ { 66 | j := i << 2 // Multiply by 4 67 | k[i] = uint32(key[j+0])<<24 | uint32(key[j+1])<<16 | uint32(key[j+2])<<8 | uint32(key[j+3]) 68 | } 69 | 70 | // Precalculate the table 71 | const delta = 0x9E3779B9 72 | var sum uint32 = 0 73 | 74 | // Two rounds of XTEA applied per loop 75 | for i := 0; i < numRounds; { 76 | c.table[i] = sum + k[sum&3] 77 | i++ 78 | sum += delta 79 | c.table[i] = sum + k[(sum>>11)&3] 80 | i++ 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /tunnel/launcher.go: -------------------------------------------------------------------------------- 1 | package tunnel 2 | 3 | import ( 4 | "fmt" 5 | "github.com/metal3d/idok/tunnel/go.crypto/ssh" 6 | "github.com/metal3d/idok/utils" 7 | "io" 8 | "log" 9 | "math/rand" 10 | "net/http" 11 | "os" 12 | "path/filepath" 13 | "time" 14 | ) 15 | 16 | // SshForward digs a tunnel to xbmc/kodi, then open a port and bind socket to 17 | // the local http server 18 | func SshHTTPForward(config *ssh.ClientConfig, file, dir string) { 19 | 20 | // Setup sshClientConn (type *ssh.ClientConn) 21 | sshClientConn, err := ssh.Dial("tcp", fmt.Sprintf("%s:%d", utils.GlobalConfig.Target, utils.GlobalConfig.Sshport), config) 22 | if err != nil { 23 | log.Fatal(err) 24 | } 25 | 26 | // Setup sshConn (type net.Conn) 27 | // Because dropbear doesn't accept :0 port to open random port 28 | // we do the randomisation ourself 29 | rand.Seed(int64(time.Now().Nanosecond())) 30 | dport := 10000 + rand.Intn(9999) 31 | tries := 0 32 | sshConn, err := sshClientConn.Listen("tcp", fmt.Sprintf("127.0.0.1:%d", dport)) 33 | for err != nil && tries < 500 { 34 | dport = 10000 + rand.Intn(9999) 35 | sshConn, err = sshClientConn.Listen("tcp", fmt.Sprintf("127.0.0.1:%d", dport)) 36 | tries++ 37 | } 38 | log.Println("Listening port on raspberry: ", dport) 39 | 40 | // send xbmc the file query 41 | go utils.Send("http", "localhost", file, dport) 42 | 43 | // now serve file 44 | fullpath := filepath.Join(dir, file) 45 | http.Serve(sshConn, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 46 | http.ServeFile(w, r, fullpath) 47 | })) 48 | } 49 | 50 | // SshForwardStdin reads stdin and stream this to distant socket 51 | // through SSH tunnel 52 | func SshForwardStdin(config *ssh.ClientConfig) { 53 | 54 | // Setup sshClientConn (type *ssh.ClientConn) 55 | sshClientConn, err := ssh.Dial("tcp", fmt.Sprintf("%s:%d", utils.GlobalConfig.Target, utils.GlobalConfig.Sshport), config) 56 | if err != nil { 57 | log.Fatal(err) 58 | } 59 | 60 | // Setup sshConn (type net.Conn) 61 | // Because dropbear doesn't accept :0 port to open random port 62 | // we do the randomisation ourself 63 | rand.Seed(int64(time.Now().Nanosecond())) 64 | dport := 10000 + rand.Intn(9999) 65 | tries := 0 66 | sshConn, err := sshClientConn.Listen("tcp", fmt.Sprintf("127.0.0.1:%d", dport)) 67 | for err != nil && tries < 500 { 68 | dport = 10000 + rand.Intn(9999) 69 | sshConn, err = sshClientConn.Listen("tcp", fmt.Sprintf("127.0.0.1:%d", dport)) 70 | tries++ 71 | } 72 | log.Println("Listening port on the target: ", dport) 73 | 74 | // send xbmc the file query 75 | go utils.Send("tcp", "127.0.0.1", "", dport) 76 | if err != nil { 77 | log.Fatal(err) 78 | } 79 | c, err := sshConn.Accept() 80 | if err != nil { 81 | log.Fatal(err) 82 | } 83 | go io.Copy(c, os.Stdin) 84 | } 85 | -------------------------------------------------------------------------------- /tunnel/parser.go: -------------------------------------------------------------------------------- 1 | package tunnel 2 | 3 | import ( 4 | "github.com/metal3d/idok/tunnel/go.crypto/ssh" 5 | "io/ioutil" 6 | "log" 7 | ) 8 | 9 | // Parse local ssh private key to get signer 10 | func parseSSHKeys(keyfile string) (ssh.Signer, error) { 11 | content, err := ioutil.ReadFile(keyfile) 12 | private, err := ssh.ParsePrivateKey(content) 13 | if err != nil { 14 | log.Println("Unable to parse private key") 15 | } 16 | return private, err 17 | } 18 | -------------------------------------------------------------------------------- /utils/const.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | const ( 4 | // message to send to stop media 5 | STOPBODY = `{"id":1,"jsonrpc":"2.0","method":"Player.Stop","params":{"playerid": %d}}` 6 | 7 | // get player id 8 | GETPLAYERBODY = `{"id":1, "jsonrpc":"2.0","method":"Player.GetActivePlayers"}` 9 | 10 | // the message to lauch local media 11 | BODY = `{ 12 | "id":1,"jsonrpc":"2.0", 13 | "method":"Player.Open", 14 | "params": { 15 | "item": { 16 | "file": "%s" 17 | } 18 | } 19 | }` 20 | 21 | YOUTUBEAPI = `{"jsonrpc": "2.0", 22 | "method": "Player.Open", 23 | "params":{"item": {"file" : "plugin://plugin.video.youtube/?action=play_video&videoid=%s" }}, 24 | "id" : "1"}` 25 | ) 26 | -------------------------------------------------------------------------------- /utils/doc.go: -------------------------------------------------------------------------------- 1 | // Configuration and methods for the basics of idok. 2 | // 3 | // There are methods to check if user pressed CTRL+C, if Kodi/XBMC is playing, and so on 4 | package utils 5 | -------------------------------------------------------------------------------- /utils/github.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "encoding/json" 5 | "errors" 6 | "log" 7 | "net/http" 8 | ) 9 | 10 | type Release struct { 11 | Url string `json:"html_url"` 12 | TagName string `json:"tag_name"` 13 | Pre bool `json:"prerelease"` 14 | } 15 | 16 | const REPO = "https://api.github.com/repos/metal3d/idok/releases" 17 | 18 | func CheckRelease() (*Release, error) { 19 | resp, err := http.Get(REPO) 20 | if err != nil { 21 | log.Println(err) 22 | } 23 | defer resp.Body.Close() 24 | r := []Release{} 25 | json.NewDecoder(resp.Body).Decode(&r) 26 | for _, release := range r { 27 | if !release.Pre { 28 | return &release, nil 29 | } 30 | } 31 | return nil, errors.New("Error fetching releases") 32 | } 33 | -------------------------------------------------------------------------------- /utils/ip.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "errors" 5 | "log" 6 | "net" 7 | ) 8 | 9 | // return local ip that matches kodi network 10 | // ignoring loopback and other net interfaces 11 | func GetLocalInterfaceIP() (string, error) { 12 | ips, _ := net.LookupIP(GlobalConfig.Target) 13 | ifaces, err := net.Interfaces() 14 | if err != nil { 15 | log.Fatalf("Error while checking you interfaces: %v", err) 16 | } 17 | for _, ip := range ips { 18 | mask := ip.DefaultMask() 19 | for _, iface := range ifaces { 20 | if iface.Flags&net.FlagLoopback != 0 { 21 | continue 22 | } 23 | 24 | addrs, _ := iface.Addrs() 25 | for _, addr := range addrs { 26 | switch v := addr.(type) { 27 | case *net.IPNet: 28 | if v.Mask.String() == mask.String() { 29 | return v.IP.String(), nil 30 | } 31 | } 32 | 33 | } 34 | } 35 | } 36 | return "", errors.New("Unable to get local ip") 37 | } 38 | -------------------------------------------------------------------------------- /utils/parsers.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "log" 5 | "net/url" 6 | ) 7 | 8 | // check if argument is a youtube url 9 | func IsYoutubeURL(query string) (bool, string) { 10 | 11 | u, err := url.ParseRequestURI(query) 12 | if err != nil { 13 | return false, "" 14 | } 15 | if u.Host == "youtu.be" { 16 | return true, u.Path[1:] 17 | } 18 | 19 | u, _ = url.ParseRequestURI(query) 20 | if u.Host == "www.youtube.com" || u.Host == "youtube.com" { 21 | v, _ := url.ParseQuery(u.RawQuery) 22 | return true, v.Get("v") 23 | } 24 | return false, "" 25 | 26 | } 27 | 28 | // check other stream 29 | // return values are "is other scheme" and "is local" 30 | func IsOtherScheme(query string) (isscheme bool, islocal bool) { 31 | u, err := url.ParseRequestURI(query) 32 | if err != nil { 33 | log.Println("not schemed") 34 | return 35 | } 36 | if len(u.Scheme) == 0 { 37 | return 38 | } 39 | isscheme = true // no error so, it's a scheme 40 | islocal = u.Host == "127.0.0.1" || u.Host == "localhost" || u.Host == "localhost.localdomain" 41 | return 42 | } 43 | -------------------------------------------------------------------------------- /utils/sender.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "bytes" 5 | "encoding/json" 6 | "fmt" 7 | "io/ioutil" 8 | "log" 9 | "net/http" 10 | "net/url" 11 | "time" 12 | ) 13 | 14 | const TICK_CHECK = 1 15 | 16 | // response of get players 17 | type itemresp struct { 18 | Id int 19 | Jsonrpc string 20 | Result []map[string]interface{} 21 | } 22 | 23 | // Send the play command to Kodi/XBMC. 24 | func Send(scheme, host, file string, port int) <-chan int { 25 | 26 | u := url.URL{Path: file} 27 | file = u.String() 28 | addr := fmt.Sprintf("%s://%s:%d/%s", scheme, host, port, file) 29 | 30 | r, err := http.Post(GlobalConfig.JsonRPC, "application/json", bytes.NewBufferString(fmt.Sprintf(BODY, addr))) 31 | if err != nil { 32 | log.Fatal(err) 33 | } 34 | response, _ := ioutil.ReadAll(r.Body) 35 | log.Println(string(response)) 36 | 37 | // and wait media end 38 | return checkPlaying() 39 | } 40 | 41 | // send basic stream... 42 | func SendBasicStream(uri string, local bool) <-chan int { 43 | _body := fmt.Sprintf(BODY, uri) 44 | 45 | r, err := http.Post(GlobalConfig.JsonRPC, "application/json", bytes.NewBufferString(_body)) 46 | if err != nil { 47 | log.Fatal(err) 48 | } 49 | response, _ := ioutil.ReadAll(r.Body) 50 | log.Println(string(response)) 51 | 52 | // handle CTRL+C to stop 53 | go OnQuit() 54 | 55 | // and wait the end of media 56 | return checkPlaying() 57 | } 58 | 59 | // Ask to play youtube video. 60 | func PlayYoutube(vidid string) <-chan int { 61 | 62 | r, err := http.Post(GlobalConfig.JsonRPC, "application/json", bytes.NewBufferString(fmt.Sprintf(YOUTUBEAPI, vidid))) 63 | if err != nil { 64 | log.Fatal(err) 65 | } 66 | response, _ := ioutil.ReadAll(r.Body) 67 | log.Println(string(response)) 68 | 69 | // handle CTRL+C to stop 70 | go OnQuit() 71 | 72 | return checkPlaying() 73 | } 74 | 75 | // test if media is playing, write 1 in returned chan when media has finished. 76 | func checkPlaying() <-chan int { 77 | tick := time.Tick(TICK_CHECK * time.Second) 78 | c := make(chan int, 0) 79 | go func() { 80 | for _ = range tick { 81 | resp := getActivePlayer() 82 | if len(resp.Result) == 0 { 83 | c <- 1 84 | } 85 | } 86 | }() 87 | return c 88 | } 89 | 90 | // return active player from XBMC. 91 | func getActivePlayer() *itemresp { 92 | r, _ := http.Post(GlobalConfig.JsonRPC, "application/json", bytes.NewBufferString(GETPLAYERBODY)) 93 | response, _ := ioutil.ReadAll(r.Body) 94 | resp := &itemresp{} 95 | resp.Result = make([]map[string]interface{}, 0) 96 | json.Unmarshal(response, resp) 97 | return resp 98 | } 99 | -------------------------------------------------------------------------------- /utils/signals.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "net/http" 7 | "os" 8 | "os/signal" 9 | "syscall" 10 | ) 11 | 12 | // when quiting (CTRL+C for example) - tell to XBMC to stop. 13 | func OnQuit() { 14 | c := make(chan os.Signal, 1) 15 | signal.Notify(c, syscall.SIGTERM, syscall.SIGINT) 16 | <-c 17 | fmt.Println("Quiting") 18 | resp := getActivePlayer() 19 | var playerid int 20 | for _, result := range resp.Result { 21 | // TODO maybe result["playerid"] is ok... 22 | for key, val := range result { 23 | if key == "playerid" { 24 | playerid = int(val.(float64)) 25 | } 26 | } 27 | } 28 | // tell to Kodi to stop 29 | http.Post(GlobalConfig.JsonRPC, "application/json", bytes.NewBufferString(fmt.Sprintf(STOPBODY, playerid))) 30 | os.Exit(0) 31 | } 32 | -------------------------------------------------------------------------------- /utils/usage.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "os" 7 | ) 8 | 9 | // Usage() prints command line documentation 10 | func Usage() { 11 | fmt.Fprintf(os.Stderr, "\nUsage: ") 12 | fmt.Fprintf(os.Stderr, "%s [options] mediafile|youtubeurl|streamurl\n\n", os.Args[0]) 13 | fmt.Fprintf(os.Stderr, "Opening external URL dosen't open local or remote port. Your media center will fetch data itself.\n\n") 14 | fmt.Fprintf(os.Stderr, "You may be able to stream stdout -> stdin:") 15 | fmt.Fprintf(os.Stderr, "\n\t%s [options] -stdin < file\n", os.Args[0]) 16 | fmt.Fprintf(os.Stderr, "Or:\n\tcommand | %s [options] -stdin \n\n", os.Args[0]) 17 | fmt.Fprintf(os.Stderr, "Using ssh option is only managed for local files.\n") 18 | fmt.Fprintf(os.Stderr, "Default mode is HTTP mode, it opens :8080 port on your host and send message to Kodi to read from that port. So, you must configure your firewall to open that port. You can override used port with -port option.\n") 19 | fmt.Fprintf(os.Stderr, "You can use SSH with -ssh option, %s will try to use key pair authtification, then use -sshpass to try login/password auth. With -ssh, you should change -sshuser if your Kodi user is not \"pi\" (default on raspbmc)\n", os.Args[0]) 20 | fmt.Fprintf(os.Stderr, "To be able to authenticate without password, use the command:\n\n\tssh-copy-id USER@KODI_HOST\n\nwhere USER is the Kodi user (pi) and KODI_HOST the ip or hostname of Kodi host.") 21 | fmt.Fprintf(os.Stderr, "\n\nOptions:\n") 22 | flag.PrintDefaults() 23 | fmt.Fprintf(os.Stderr, ` 24 | You can create a configuration file in current directory, or: 25 | - $HOME/.config/idok/idok.conf 26 | - $HOME/.local/etc/idok.conf 27 | - /etc/idok.conf 28 | 29 | Configuration file will set default options. Using options in the command line will override configuration file 30 | 31 | The -conf-example option prints a default configuration file. 32 | `) 33 | fmt.Fprintf(os.Stderr, "\n") 34 | } 35 | --------------------------------------------------------------------------------