updated xorm branch with tor support
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
ecacc1963e
commit
bdf7f6195e
1
.gitignore
vendored
1
.gitignore
vendored
@ -2,3 +2,4 @@
|
|||||||
/*.ini
|
/*.ini
|
||||||
/*.json
|
/*.json
|
||||||
/dist
|
/dist
|
||||||
|
/data-dir*
|
||||||
|
@ -1,14 +1,13 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
"git.paulbsd.com/paulbsd/coronafana/src/config"
|
"git.paulbsd.com/paulbsd/coronafana/src/config"
|
||||||
"git.paulbsd.com/paulbsd/coronafana/src/coronafana"
|
"git.paulbsd.com/paulbsd/coronafana/src/coronafana"
|
||||||
|
"git.paulbsd.com/paulbsd/coronafana/src/database"
|
||||||
|
"git.paulbsd.com/paulbsd/coronafana/src/network"
|
||||||
_ "github.com/lib/pq"
|
_ "github.com/lib/pq"
|
||||||
"xorm.io/xorm"
|
|
||||||
"xorm.io/xorm/names"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@ -21,32 +20,33 @@ func main() {
|
|||||||
log.Fatalln(err)
|
log.Fatalln(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
db, err := xorm.NewEngine("postgres",
|
err = database.InitDatabase(&cfg)
|
||||||
fmt.Sprintf("user=%s password=%s host=%s dbname=%s sslmode=disable",
|
|
||||||
cfg.DbUsername,
|
|
||||||
cfg.DbPassword,
|
|
||||||
cfg.DbHostname,
|
|
||||||
cfg.DbName))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalln(err)
|
log.Fatalln(err)
|
||||||
}
|
}
|
||||||
defer db.Close()
|
defer cfg.Db.Close()
|
||||||
|
|
||||||
db.SetMapper(names.GonicMapper{})
|
t, d, dc, err := network.InitTorSession()
|
||||||
db.ShowSQL(cfg.Debug)
|
if err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
for object := range []interface{}{new(coronafana.Coronaglobaldata), new(coronafana.Coronapaysdata)} {
|
|
||||||
err = db.Sync2(object)
|
|
||||||
}
|
}
|
||||||
|
defer dc()
|
||||||
|
defer t.Close()
|
||||||
|
|
||||||
cr, err = coronafana.GetData(cfg)
|
cr, err = coronafana.GetData(cfg, d)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalln(err)
|
log.Fatalln(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process data
|
// Process global data
|
||||||
err = cr.InsertData(cfg, *db)
|
err = coronafana.InsertData(cfg, cr.Coronaglobaldata)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalln(err)
|
log.Println(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process pays data
|
||||||
|
err = coronafana.InsertData(cfg, cr.Coronapaysdata)
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
9
go.mod
9
go.mod
@ -3,11 +3,14 @@ module git.paulbsd.com/paulbsd/coronafana
|
|||||||
go 1.14
|
go 1.14
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/go-sql-driver/mysql v1.5.0 // indirect
|
github.com/cretz/bine v0.1.0
|
||||||
github.com/jinzhu/gorm v1.9.12 // indirect
|
github.com/ipsn/go-libtor v1.0.230 // indirect
|
||||||
github.com/jmoiron/sqlx v1.2.0 // indirect
|
|
||||||
github.com/lib/pq v1.8.0
|
github.com/lib/pq v1.8.0
|
||||||
|
github.com/mattn/go-sqlite3 v2.0.1+incompatible // indirect
|
||||||
github.com/smartystreets/goconvey v1.6.4 // indirect
|
github.com/smartystreets/goconvey v1.6.4 // indirect
|
||||||
|
golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9 // indirect
|
||||||
|
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b // indirect
|
||||||
|
golang.org/x/sys v0.0.0-20201113135734-0a15ea8d9b02 // indirect
|
||||||
gopkg.in/ini.v1 v1.54.0
|
gopkg.in/ini.v1 v1.54.0
|
||||||
xorm.io/xorm v1.0.4
|
xorm.io/xorm v1.0.4
|
||||||
)
|
)
|
||||||
|
57
go.sum
57
go.sum
@ -1,48 +1,44 @@
|
|||||||
|
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGqTOXqu2aRi/XEQxDCBwM8yJtE6s=
|
||||||
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU=
|
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU=
|
||||||
github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc=
|
github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc=
|
||||||
github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
|
github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
|
||||||
|
github.com/cretz/bine v0.1.0 h1:1/fvhLE+fk0bPzjdO5Ci+0ComYxEMuB1JhM4X5skT3g=
|
||||||
|
github.com/cretz/bine v0.1.0/go.mod h1:6PF6fWAvYtwjRGkAuDEJeWNOv3a2hUouSP/yRYXmvHw=
|
||||||
|
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd h1:83Wprp6ROGeiHFAP8WJdI2RoxALQYgdllERc3N5N2DM=
|
|
||||||
github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
|
||||||
github.com/denisenkom/go-mssqldb v0.0.0-20200428022330-06a60b6afbbc/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
github.com/denisenkom/go-mssqldb v0.0.0-20200428022330-06a60b6afbbc/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
||||||
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5 h1:Yzb9+7DPaBjB8zlTR87/ElzFsnQfuHnVUVqpZZIcV5Y=
|
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
||||||
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0=
|
|
||||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||||
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
|
||||||
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
|
||||||
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
|
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
|
||||||
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY=
|
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY=
|
||||||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
|
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
|
||||||
|
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
|
||||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w=
|
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w=
|
||||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
|
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
|
||||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||||
|
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
||||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||||
github.com/jinzhu/gorm v1.9.12 h1:Drgk1clyWT9t9ERbzHza6Mj/8FY/CqMyVzOiHviMo6Q=
|
github.com/ipsn/go-libtor v1.0.230 h1:09uTWF+K/KBjc6DVbRnOz41RwGwGJO+ESwou23LR+zc=
|
||||||
github.com/jinzhu/gorm v1.9.12/go.mod h1:vhTjlKSJUTWNtcbQtrMBFCxy7eXTzeCAzfL5fBZT/Qs=
|
github.com/ipsn/go-libtor v1.0.230/go.mod h1:6rIeHU7irp8ZH8E/JqaEOKlD6s4vSSUh4ngHelhlSMw=
|
||||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
github.com/ipsn/go-libtor v1.0.329 h1:ctrgIxm+Fiwk3oVA0x0pwNOzZWTFNoe4tanS9c3cVhc=
|
||||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
github.com/ipsn/go-libtor v1.0.329/go.mod h1:6rIeHU7irp8ZH8E/JqaEOKlD6s4vSSUh4ngHelhlSMw=
|
||||||
github.com/jinzhu/now v1.0.1 h1:HjfetcXq097iXP0uoPCdnM4Efp5/9MsM0/M+XOTeR3M=
|
|
||||||
github.com/jinzhu/now v1.0.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
|
||||||
github.com/jmoiron/sqlx v1.2.0 h1:41Ip0zITnmWNR/vHV+S4m+VoUivnWY5E4OJfLZjCJMA=
|
|
||||||
github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks=
|
|
||||||
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
|
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
|
||||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
|
||||||
github.com/lib/pq v1.1.1 h1:sJZmqHoEaY7f+NPP8pgLB/WxulyR3fewgCM2qaSlBb4=
|
|
||||||
github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
|
||||||
github.com/lib/pq v1.7.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
github.com/lib/pq v1.7.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||||
github.com/lib/pq v1.8.0 h1:9xohqzkUwzR4Ga4ivdTcawVS89YSDVxXMa3xJX3cGzg=
|
github.com/lib/pq v1.8.0 h1:9xohqzkUwzR4Ga4ivdTcawVS89YSDVxXMa3xJX3cGzg=
|
||||||
github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||||
github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
|
||||||
github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus=
|
github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus=
|
||||||
github.com/mattn/go-sqlite3 v2.0.1+incompatible h1:xQ15muvnzGBHpIpdrNi1DA5x0+TcBZzsIDwmw9uTHzw=
|
github.com/mattn/go-sqlite3 v2.0.1+incompatible h1:xQ15muvnzGBHpIpdrNi1DA5x0+TcBZzsIDwmw9uTHzw=
|
||||||
github.com/mattn/go-sqlite3 v2.0.1+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
github.com/mattn/go-sqlite3 v2.0.1+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
|
github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs=
|
||||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
|
github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU=
|
||||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
|
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
|
||||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||||
@ -50,36 +46,53 @@ github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIK
|
|||||||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
|
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
|
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
|
||||||
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
|
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
|
||||||
github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0=
|
github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c h1:Vj5n4GlwjmQteupaxJ9+0FNOmBrHfq7vN4btdGoDZgI=
|
||||||
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd h1:GGJVjV8waZKRHrgwvtH66z9ZGVurTD1MT0n1Bb+q4aM=
|
golang.org/x/crypto v0.0.0-20190404164418-38d8ce5564a5/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
|
||||||
golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
|
golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9 h1:umElSU9WZirRdgu2yFHY0ayQkEnKiOC1TtM3fWXFnoU=
|
||||||
|
golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e h1:3G+cUijn7XD+S4eJFddp53Pv7+slrESplyjG25HgL+k=
|
||||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||||
|
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b h1:uwuIcX0g4Yl1NC5XAz37xsr2lTtcqevgzYNVt49waME=
|
||||||
|
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA=
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
|
||||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20201113135734-0a15ea8d9b02 h1:5Ftd3YbC/kANXWCBjvppvUmv1BMakgFcBKA7MpYYp4M=
|
||||||
|
golang.org/x/sys v0.0.0-20201113135734-0a15ea8d9b02/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
|
||||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||||
gopkg.in/ini.v1 v1.54.0 h1:oM5ElzbIi7gwLnNbPX2M25ED1vSAK3B6dex50eS/6Fs=
|
gopkg.in/ini.v1 v1.54.0 h1:oM5ElzbIi7gwLnNbPX2M25ED1vSAK3B6dex50eS/6Fs=
|
||||||
gopkg.in/ini.v1 v1.54.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
gopkg.in/ini.v1 v1.54.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||||
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
xorm.io/builder v0.3.7 h1:2pETdKRK+2QG4mLX4oODHEhn5Z8j1m8sXa7jfu+/SZI=
|
xorm.io/builder v0.3.7 h1:2pETdKRK+2QG4mLX4oODHEhn5Z8j1m8sXa7jfu+/SZI=
|
||||||
xorm.io/builder v0.3.7/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE=
|
xorm.io/builder v0.3.7/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE=
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
|
|
||||||
"git.paulbsd.com/paulbsd/coronafana/utils"
|
"git.paulbsd.com/paulbsd/coronafana/utils"
|
||||||
"gopkg.in/ini.v1"
|
"gopkg.in/ini.v1"
|
||||||
|
"xorm.io/xorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetConfig fetch configuration
|
// GetConfig fetch configuration
|
||||||
@ -45,6 +46,7 @@ func (config *Config) GetConfig() (err error) {
|
|||||||
// Config is the global config of g2g
|
// Config is the global config of g2g
|
||||||
type Config struct {
|
type Config struct {
|
||||||
CoronaURL string
|
CoronaURL string
|
||||||
|
Db *xorm.Engine
|
||||||
Debug bool
|
Debug bool
|
||||||
Diffdays int `ini:"diffdays"`
|
Diffdays int `ini:"diffdays"`
|
||||||
DbHostname string `ini:"db_hostname"`
|
DbHostname string `ini:"db_hostname"`
|
||||||
|
@ -6,16 +6,18 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.paulbsd.com/paulbsd/coronafana/src/config"
|
"git.paulbsd.com/paulbsd/coronafana/src/config"
|
||||||
|
"github.com/cretz/bine/tor"
|
||||||
"xorm.io/xorm"
|
"xorm.io/xorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetData fetch data from open data portal
|
// GetData fetch data from open data portal
|
||||||
func GetData(cfg config.Config) (cr Coronafana, err error) {
|
func GetData(cfg config.Config, d *tor.Dialer) (cr Coronafana, err error) {
|
||||||
var client http.Client
|
var client = &http.Client{Transport: &http.Transport{DialContext: d.DialContext}}
|
||||||
|
|
||||||
log.Println("Getting JSON file ...")
|
log.Println("Getting JSON file ...")
|
||||||
|
|
||||||
@ -46,73 +48,59 @@ func GetData(cfg config.Config) (cr Coronafana, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// InsertData insert data to MySQL / MariaDB
|
// InsertData insert data to MySQL / MariaDB
|
||||||
func (cr Coronafana) InsertData(cfg config.Config, db xorm.Engine) (err error) {
|
func InsertData(cfg config.Config, data interface{}) (err error) {
|
||||||
var tx *xorm.Session
|
var tx *xorm.Session
|
||||||
var i int
|
var i int
|
||||||
var cgd []Coronaglobaldata
|
|
||||||
var cpd []Coronapaysdata
|
|
||||||
var globalparseddate time.Time
|
|
||||||
var paysparseddate time.Time
|
|
||||||
|
|
||||||
tx = db.NewSession()
|
var cd []interface{}
|
||||||
|
var parseddate time.Time
|
||||||
|
|
||||||
|
tx = cfg.Db.NewSession()
|
||||||
defer tx.Close()
|
defer tx.Close()
|
||||||
|
|
||||||
log.Println("Getting max dates")
|
log.Println("Getting max dates")
|
||||||
|
|
||||||
err = db.Desc("date").Limit(1, cfg.Diffdays).Find(&cgd)
|
err = cfg.Db.Desc("date").Limit(1, cfg.Diffdays).Find(&data)
|
||||||
if len(cgd) > 0 {
|
|
||||||
globalparseddate = cgd[0].Date
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
err = db.Desc("date").Limit(1, cfg.Diffdays).Find(&cpd)
|
if len(cd) > 0 {
|
||||||
if len(cgd) > 0 {
|
if reflect.TypeOf(data) == reflect.TypeOf(new(Coronaglobaldata)) {
|
||||||
paysparseddate = cpd[0].Date
|
datac := data.([]Coronaglobaldata)
|
||||||
|
parseddate = datac[0].Date
|
||||||
|
} else if reflect.TypeOf(data) == reflect.TypeOf(new(Coronapaysdata)) {
|
||||||
|
datac := data.([]Coronapaysdata)
|
||||||
|
parseddate = datac[0].Date
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tx.Begin()
|
tx.Begin()
|
||||||
|
log.Println("Start inserting data ...")
|
||||||
|
|
||||||
i = 0
|
if reflect.TypeOf(data) == reflect.TypeOf([]Coronaglobaldata{}) {
|
||||||
log.Println("Start inserting global data ...")
|
for _, dt := range data.([]Coronaglobaldata) {
|
||||||
for _, dt := range cr.Coronaglobaldata {
|
if dt.Date, err = GetParsedDate(dt.DateString); dt.Date.After(parseddate) {
|
||||||
if dt.Date, err = GetParsedDate(dt.DateString); dt.Date.After(globalparseddate) {
|
_, err = tx.Insert(&dt)
|
||||||
_, err = tx.Insert(&dt)
|
if err != nil {
|
||||||
if err != nil {
|
if !strings.Contains(err.Error(), "Error 1062") {
|
||||||
if !strings.Contains(err.Error(), "Error 1062") {
|
return
|
||||||
return
|
}
|
||||||
}
|
}
|
||||||
|
i++
|
||||||
}
|
}
|
||||||
i++
|
|
||||||
}
|
}
|
||||||
}
|
} else if reflect.TypeOf(data) == reflect.TypeOf([]Coronapaysdata{}) {
|
||||||
|
for _, dt := range data.([]Coronapaysdata) {
|
||||||
err = tx.Commit()
|
if dt.Date, err = GetParsedDate(dt.DateString); dt.Date.After(parseddate) {
|
||||||
if err != nil {
|
_, err = tx.Insert(&dt)
|
||||||
return
|
if err != nil {
|
||||||
}
|
if !strings.Contains(err.Error(), "Error 1062") {
|
||||||
|
return
|
||||||
if i > 0 {
|
}
|
||||||
log.Println(fmt.Sprintf("%d entries inserted", i))
|
|
||||||
} else {
|
|
||||||
log.Println("No entry inserted")
|
|
||||||
}
|
|
||||||
|
|
||||||
i = 0
|
|
||||||
log.Println("Start inserting pays data ...")
|
|
||||||
for _, dt := range cr.Coronapaysdata {
|
|
||||||
if dt.Date, err = GetParsedDate(dt.DateString); dt.Date.After(paysparseddate) {
|
|
||||||
_, err = tx.Insert(&dt)
|
|
||||||
if err != nil {
|
|
||||||
if !strings.Contains(err.Error(), "Error 1062") {
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
i++
|
||||||
}
|
}
|
||||||
i++
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
39
src/database/main.go
Normal file
39
src/database/main.go
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
package database
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"git.paulbsd.com/paulbsd/coronafana/src/config"
|
||||||
|
"git.paulbsd.com/paulbsd/coronafana/src/coronafana"
|
||||||
|
"xorm.io/xorm"
|
||||||
|
"xorm.io/xorm/names"
|
||||||
|
)
|
||||||
|
|
||||||
|
// InitDatabase ...
|
||||||
|
func InitDatabase(cfg *config.Config) (err error) {
|
||||||
|
var tables = []interface{}{
|
||||||
|
new(coronafana.Coronaglobaldata),
|
||||||
|
new(coronafana.Coronapaysdata),
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg.Db, err = xorm.NewEngine("postgres",
|
||||||
|
fmt.Sprintf("user=%s password=%s host=%s dbname=%s sslmode=disable",
|
||||||
|
cfg.DbUsername,
|
||||||
|
cfg.DbPassword,
|
||||||
|
cfg.DbHostname,
|
||||||
|
cfg.DbName))
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg.Db.SetMapper(names.GonicMapper{})
|
||||||
|
cfg.Db.ShowSQL(cfg.Debug)
|
||||||
|
|
||||||
|
for _, object := range tables {
|
||||||
|
err = cfg.Db.Sync2(object)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
25
src/network/main.go
Normal file
25
src/network/main.go
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
package network
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"log"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/cretz/bine/tor"
|
||||||
|
)
|
||||||
|
|
||||||
|
// InitTorSession initialize a tor session
|
||||||
|
func InitTorSession() (t *tor.Tor, dialer *tor.Dialer, dialCancel context.CancelFunc, err error) {
|
||||||
|
t, err = tor.Start(nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
log.Panicf("Failed to start tor: %v", err)
|
||||||
|
}
|
||||||
|
// Wait at most a minute to start network and get
|
||||||
|
dialCtx, dialCancel := context.WithTimeout(context.Background(), time.Minute)
|
||||||
|
|
||||||
|
dialer, err = t.Dialer(dialCtx, nil)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
21
vendor/github.com/cretz/bine/LICENSE
generated
vendored
Normal file
21
vendor/github.com/cretz/bine/LICENSE
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2018 Chad Retz
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
108
vendor/github.com/cretz/bine/control/cmd_authenticate.go
generated
vendored
Normal file
108
vendor/github.com/cretz/bine/control/cmd_authenticate.go
generated
vendored
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
package control
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/hmac"
|
||||||
|
"crypto/rand"
|
||||||
|
"crypto/sha256"
|
||||||
|
"encoding/hex"
|
||||||
|
"io/ioutil"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Authenticate authenticates with the Tor instance using the "best" possible
|
||||||
|
// authentication method if not already authenticated and sets the Authenticated
|
||||||
|
// field. The password argument is optional, and will only be used if the
|
||||||
|
// "SAFECOOKIE" and "NULL" authentication methods are not available and
|
||||||
|
// "HASHEDPASSWORD" is.
|
||||||
|
func (c *Conn) Authenticate(password string) error {
|
||||||
|
if c.Authenticated {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
// Determine the supported authentication methods, and the cookie path.
|
||||||
|
pi, err := c.ProtocolInfo()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// Get the bytes to pass to with authenticate
|
||||||
|
var authBytes []byte
|
||||||
|
if pi.HasAuthMethod("NULL") {
|
||||||
|
// No auth bytes
|
||||||
|
} else if pi.HasAuthMethod("SAFECOOKIE") {
|
||||||
|
if pi.CookieFile == "" {
|
||||||
|
return c.protoErr("Invalid (empty) COOKIEFILE")
|
||||||
|
}
|
||||||
|
cookie, err := ioutil.ReadFile(pi.CookieFile)
|
||||||
|
if err != nil {
|
||||||
|
return c.protoErr("Failed to read COOKIEFILE: %v", err)
|
||||||
|
} else if len(cookie) != 32 {
|
||||||
|
return c.protoErr("Invalid cookie file length: %v", len(cookie))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send an AUTHCHALLENGE command, and parse the response.
|
||||||
|
var clientNonce [32]byte
|
||||||
|
if _, err := rand.Read(clientNonce[:]); err != nil {
|
||||||
|
return c.protoErr("Failed to generate clientNonce: %v", err)
|
||||||
|
}
|
||||||
|
resp, err := c.SendRequest("AUTHCHALLENGE %s %s", "SAFECOOKIE", hex.EncodeToString(clientNonce[:]))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
splitResp := strings.Split(resp.Reply, " ")
|
||||||
|
if len(splitResp) != 3 || !strings.HasPrefix(splitResp[1], "SERVERHASH=") ||
|
||||||
|
!strings.HasPrefix(splitResp[2], "SERVERNONCE=") {
|
||||||
|
return c.protoErr("Invalid AUTHCHALLENGE response")
|
||||||
|
}
|
||||||
|
serverHash, err := hex.DecodeString(splitResp[1][11:])
|
||||||
|
if err != nil {
|
||||||
|
return c.protoErr("Failed to decode ServerHash: %v", err)
|
||||||
|
}
|
||||||
|
if len(serverHash) != 32 {
|
||||||
|
return c.protoErr("Invalid ServerHash length: %d", len(serverHash))
|
||||||
|
}
|
||||||
|
serverNonce, err := hex.DecodeString(splitResp[2][12:])
|
||||||
|
if err != nil {
|
||||||
|
return c.protoErr("Failed to decode ServerNonce: %v", err)
|
||||||
|
}
|
||||||
|
if len(serverNonce) != 32 {
|
||||||
|
return c.protoErr("Invalid ServerNonce length: %d", len(serverNonce))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate the ServerHash.
|
||||||
|
m := hmac.New(sha256.New, []byte("Tor safe cookie authentication server-to-controller hash"))
|
||||||
|
m.Write(cookie)
|
||||||
|
m.Write(clientNonce[:])
|
||||||
|
m.Write(serverNonce)
|
||||||
|
dervServerHash := m.Sum(nil)
|
||||||
|
if !hmac.Equal(serverHash, dervServerHash) {
|
||||||
|
return c.protoErr("invalid ServerHash: mismatch")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate the ClientHash, and issue the AUTHENTICATE.
|
||||||
|
m = hmac.New(sha256.New, []byte("Tor safe cookie authentication controller-to-server hash"))
|
||||||
|
m.Write(cookie)
|
||||||
|
m.Write(clientNonce[:])
|
||||||
|
m.Write(serverNonce)
|
||||||
|
authBytes = m.Sum(nil)
|
||||||
|
} else if pi.HasAuthMethod("HASHEDPASSWORD") {
|
||||||
|
// Despite the name HASHEDPASSWORD, the raw password is actually sent. According to the code, this can either be
|
||||||
|
// a QuotedString, or base16 encoded, so go with the later since it's easier to handle.
|
||||||
|
if password == "" {
|
||||||
|
return c.protoErr("password auth needs a password")
|
||||||
|
}
|
||||||
|
authBytes = []byte(password)
|
||||||
|
} else {
|
||||||
|
return c.protoErr("No supported authentication methods")
|
||||||
|
}
|
||||||
|
// Send it
|
||||||
|
if err = c.sendAuthenticate(authBytes); err == nil {
|
||||||
|
c.Authenticated = true
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Conn) sendAuthenticate(byts []byte) error {
|
||||||
|
if len(byts) == 0 {
|
||||||
|
return c.sendRequestIgnoreResponse("AUTHENTICATE")
|
||||||
|
}
|
||||||
|
return c.sendRequestIgnoreResponse("AUTHENTICATE %v", hex.EncodeToString(byts))
|
||||||
|
}
|
38
vendor/github.com/cretz/bine/control/cmd_circuit.go
generated
vendored
Normal file
38
vendor/github.com/cretz/bine/control/cmd_circuit.go
generated
vendored
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
package control
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ExtendCircuit invokes EXTENDCIRCUIT and returns the circuit ID on success.
|
||||||
|
func (c *Conn) ExtendCircuit(circuitID string, path []string, purpose string) (string, error) {
|
||||||
|
if circuitID == "" {
|
||||||
|
circuitID = "0"
|
||||||
|
}
|
||||||
|
cmd := "EXTENDCIRCUIT " + circuitID
|
||||||
|
if len(path) > 0 {
|
||||||
|
cmd += " " + strings.Join(path, ",")
|
||||||
|
}
|
||||||
|
if purpose != "" {
|
||||||
|
cmd += " purpose=" + purpose
|
||||||
|
}
|
||||||
|
resp, err := c.SendRequest(cmd)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return resp.Reply[strings.LastIndexByte(resp.Reply, ' ')+1:], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetCircuitPurpose invokes SETCIRCUITPURPOSE.
|
||||||
|
func (c *Conn) SetCircuitPurpose(circuitID string, purpose string) error {
|
||||||
|
return c.sendRequestIgnoreResponse("SETCIRCUITPURPOSE %v purpose=%v", circuitID, purpose)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CloseCircuit invokes CLOSECIRCUIT.
|
||||||
|
func (c *Conn) CloseCircuit(circuitID string, flags []string) error {
|
||||||
|
cmd := "CLOSECIRCUIT " + circuitID
|
||||||
|
for _, flag := range flags {
|
||||||
|
cmd += " " + flag
|
||||||
|
}
|
||||||
|
return c.sendRequestIgnoreResponse(cmd)
|
||||||
|
}
|
65
vendor/github.com/cretz/bine/control/cmd_conf.go
generated
vendored
Normal file
65
vendor/github.com/cretz/bine/control/cmd_conf.go
generated
vendored
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
package control
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/cretz/bine/torutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SetConf invokes SETCONF.
|
||||||
|
func (c *Conn) SetConf(entries ...*KeyVal) error {
|
||||||
|
return c.sendSetConf("SETCONF", entries)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResetConf invokes RESETCONF.
|
||||||
|
func (c *Conn) ResetConf(entries ...*KeyVal) error {
|
||||||
|
return c.sendSetConf("RESETCONF", entries)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Conn) sendSetConf(cmd string, entries []*KeyVal) error {
|
||||||
|
for _, entry := range entries {
|
||||||
|
cmd += " " + entry.Key
|
||||||
|
if entry.ValSet() {
|
||||||
|
cmd += "=" + torutil.EscapeSimpleQuotedStringIfNeeded(entry.Val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return c.sendRequestIgnoreResponse(cmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetConf invokes GETCONF and returns the values for the requested keys.
|
||||||
|
func (c *Conn) GetConf(keys ...string) ([]*KeyVal, error) {
|
||||||
|
resp, err := c.SendRequest("GETCONF %v", strings.Join(keys, " "))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
data := resp.DataWithReply()
|
||||||
|
ret := make([]*KeyVal, 0, len(data))
|
||||||
|
for _, data := range data {
|
||||||
|
key, val, ok := torutil.PartitionString(data, '=')
|
||||||
|
entry := &KeyVal{Key: key}
|
||||||
|
if ok {
|
||||||
|
if entry.Val, err = torutil.UnescapeSimpleQuotedStringIfNeeded(val); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if len(entry.Val) == 0 {
|
||||||
|
entry.ValSetAndEmpty = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ret = append(ret, entry)
|
||||||
|
}
|
||||||
|
return ret, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SaveConf invokes SAVECONF.
|
||||||
|
func (c *Conn) SaveConf(force bool) error {
|
||||||
|
cmd := "SAVECONF"
|
||||||
|
if force {
|
||||||
|
cmd += " FORCE"
|
||||||
|
}
|
||||||
|
return c.sendRequestIgnoreResponse(cmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoadConf invokes LOADCONF.
|
||||||
|
func (c *Conn) LoadConf(conf string) error {
|
||||||
|
return c.sendRequestIgnoreResponse("+LOADCONF\r\n%v\r\n.", conf)
|
||||||
|
}
|
1218
vendor/github.com/cretz/bine/control/cmd_event.go
generated
vendored
Normal file
1218
vendor/github.com/cretz/bine/control/cmd_event.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
23
vendor/github.com/cretz/bine/control/cmd_hiddenservice.go
generated
vendored
Normal file
23
vendor/github.com/cretz/bine/control/cmd_hiddenservice.go
generated
vendored
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
package control
|
||||||
|
|
||||||
|
// GetHiddenServiceDescriptorAsync invokes HSFETCH.
|
||||||
|
func (c *Conn) GetHiddenServiceDescriptorAsync(address string, server string) error {
|
||||||
|
cmd := "HSFETCH " + address
|
||||||
|
if server != "" {
|
||||||
|
cmd += " SERVER=" + server
|
||||||
|
}
|
||||||
|
return c.sendRequestIgnoreResponse(cmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
// PostHiddenServiceDescriptorAsync invokes HSPOST.
|
||||||
|
func (c *Conn) PostHiddenServiceDescriptorAsync(desc string, servers []string, address string) error {
|
||||||
|
cmd := "+HSPOST"
|
||||||
|
for _, server := range servers {
|
||||||
|
cmd += " SERVER=" + server
|
||||||
|
}
|
||||||
|
if address != "" {
|
||||||
|
cmd += "HSADDRESS=" + address
|
||||||
|
}
|
||||||
|
cmd += "\r\n" + desc + "\r\n."
|
||||||
|
return c.sendRequestIgnoreResponse(cmd)
|
||||||
|
}
|
92
vendor/github.com/cretz/bine/control/cmd_misc.go
generated
vendored
Normal file
92
vendor/github.com/cretz/bine/control/cmd_misc.go
generated
vendored
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
package control
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/cretz/bine/torutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Signal invokes SIGNAL.
|
||||||
|
func (c *Conn) Signal(signal string) error {
|
||||||
|
return c.sendRequestIgnoreResponse("SIGNAL %v", signal)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Quit invokes QUIT.
|
||||||
|
func (c *Conn) Quit() error {
|
||||||
|
return c.sendRequestIgnoreResponse("QUIT")
|
||||||
|
}
|
||||||
|
|
||||||
|
// MapAddresses invokes MAPADDRESS and returns mapped addresses.
|
||||||
|
func (c *Conn) MapAddresses(addresses ...*KeyVal) ([]*KeyVal, error) {
|
||||||
|
cmd := "MAPADDRESS"
|
||||||
|
for _, address := range addresses {
|
||||||
|
cmd += " " + address.Key + "=" + address.Val
|
||||||
|
}
|
||||||
|
resp, err := c.SendRequest(cmd)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
data := resp.DataWithReply()
|
||||||
|
ret := make([]*KeyVal, 0, len(data))
|
||||||
|
for _, address := range data {
|
||||||
|
mappedAddress := &KeyVal{}
|
||||||
|
mappedAddress.Key, mappedAddress.Val, _ = torutil.PartitionString(address, '=')
|
||||||
|
ret = append(ret, mappedAddress)
|
||||||
|
}
|
||||||
|
return ret, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetInfo invokes GETINTO and returns values for requested keys.
|
||||||
|
func (c *Conn) GetInfo(keys ...string) ([]*KeyVal, error) {
|
||||||
|
resp, err := c.SendRequest("GETINFO %v", strings.Join(keys, " "))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
ret := make([]*KeyVal, 0, len(resp.Data))
|
||||||
|
for _, val := range resp.Data {
|
||||||
|
infoVal := &KeyVal{}
|
||||||
|
infoVal.Key, infoVal.Val, _ = torutil.PartitionString(val, '=')
|
||||||
|
if infoVal.Val, err = torutil.UnescapeSimpleQuotedStringIfNeeded(infoVal.Val); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
ret = append(ret, infoVal)
|
||||||
|
}
|
||||||
|
return ret, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// PostDescriptor invokes POSTDESCRIPTOR.
|
||||||
|
func (c *Conn) PostDescriptor(descriptor string, purpose string, cache string) error {
|
||||||
|
cmd := "+POSTDESCRIPTOR"
|
||||||
|
if purpose != "" {
|
||||||
|
cmd += " purpose=" + purpose
|
||||||
|
}
|
||||||
|
if cache != "" {
|
||||||
|
cmd += " cache=" + cache
|
||||||
|
}
|
||||||
|
cmd += "\r\n" + descriptor + "\r\n."
|
||||||
|
return c.sendRequestIgnoreResponse(cmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UseFeatures invokes USEFEATURE.
|
||||||
|
func (c *Conn) UseFeatures(features ...string) error {
|
||||||
|
return c.sendRequestIgnoreResponse("USEFEATURE " + strings.Join(features, " "))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResolveAsync invokes RESOLVE.
|
||||||
|
func (c *Conn) ResolveAsync(address string, reverse bool) error {
|
||||||
|
cmd := "RESOLVE "
|
||||||
|
if reverse {
|
||||||
|
cmd += "mode=reverse "
|
||||||
|
}
|
||||||
|
return c.sendRequestIgnoreResponse(cmd + address)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TakeOwnership invokes TAKEOWNERSHIP.
|
||||||
|
func (c *Conn) TakeOwnership() error {
|
||||||
|
return c.sendRequestIgnoreResponse("TAKEOWNERSHIP")
|
||||||
|
}
|
||||||
|
|
||||||
|
// DropGuards invokes DROPGUARDS.
|
||||||
|
func (c *Conn) DropGuards() error {
|
||||||
|
return c.sendRequestIgnoreResponse("DROPGUARDS")
|
||||||
|
}
|
201
vendor/github.com/cretz/bine/control/cmd_onion.go
generated
vendored
Normal file
201
vendor/github.com/cretz/bine/control/cmd_onion.go
generated
vendored
Normal file
@ -0,0 +1,201 @@
|
|||||||
|
package control
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/rsa"
|
||||||
|
"crypto/x509"
|
||||||
|
"encoding/base64"
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/cretz/bine/torutil"
|
||||||
|
"github.com/cretz/bine/torutil/ed25519"
|
||||||
|
)
|
||||||
|
|
||||||
|
// KeyType is a key type for Key in AddOnion.
|
||||||
|
type KeyType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
// KeyTypeNew is NEW.
|
||||||
|
KeyTypeNew KeyType = "NEW"
|
||||||
|
// KeyTypeRSA1024 is RSA1024.
|
||||||
|
KeyTypeRSA1024 KeyType = "RSA1024"
|
||||||
|
// KeyTypeED25519V3 is ED25519-V3.
|
||||||
|
KeyTypeED25519V3 KeyType = "ED25519-V3"
|
||||||
|
)
|
||||||
|
|
||||||
|
// KeyAlgo is a key algorithm for GenKey on AddOnion.
|
||||||
|
type KeyAlgo string
|
||||||
|
|
||||||
|
const (
|
||||||
|
// KeyAlgoBest is BEST.
|
||||||
|
KeyAlgoBest KeyAlgo = "BEST"
|
||||||
|
// KeyAlgoRSA1024 is RSA1024.
|
||||||
|
KeyAlgoRSA1024 KeyAlgo = "RSA1024"
|
||||||
|
// KeyAlgoED25519V3 is ED25519-V3.
|
||||||
|
KeyAlgoED25519V3 KeyAlgo = "ED25519-V3"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Key is a type of key to use for AddOnion. Implementations include GenKey,
|
||||||
|
// RSAKey, and ED25519Key.
|
||||||
|
type Key interface {
|
||||||
|
// Type is the KeyType for AddOnion.
|
||||||
|
Type() KeyType
|
||||||
|
// Blob is the serialized key for AddOnion.
|
||||||
|
Blob() string
|
||||||
|
}
|
||||||
|
|
||||||
|
// KeyFromString creates a Key for AddOnion based on a response string.
|
||||||
|
func KeyFromString(str string) (Key, error) {
|
||||||
|
typ, blob, _ := torutil.PartitionString(str, ':')
|
||||||
|
switch KeyType(typ) {
|
||||||
|
case KeyTypeNew:
|
||||||
|
return GenKeyFromBlob(blob), nil
|
||||||
|
case KeyTypeRSA1024:
|
||||||
|
return RSA1024KeyFromBlob(blob)
|
||||||
|
case KeyTypeED25519V3:
|
||||||
|
return ED25519KeyFromBlob(blob)
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("Unrecognized key type: %v", typ)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GenKey is a Key for AddOnion that asks Tor to generate a key for the given
|
||||||
|
// algorithm.
|
||||||
|
type GenKey KeyAlgo
|
||||||
|
|
||||||
|
// GenKeyFromBlob creates a GenKey for the given response blob which is a
|
||||||
|
// KeyAlgo.
|
||||||
|
func GenKeyFromBlob(blob string) GenKey { return GenKey(KeyAlgo(blob)) }
|
||||||
|
|
||||||
|
// Type implements Key.Type.
|
||||||
|
func (GenKey) Type() KeyType { return KeyTypeNew }
|
||||||
|
|
||||||
|
// Blob implements Key.Blob.
|
||||||
|
func (g GenKey) Blob() string { return string(g) }
|
||||||
|
|
||||||
|
// RSAKey is a Key for AddOnion that is a RSA-1024 key (i.e. v2).
|
||||||
|
type RSAKey struct{ *rsa.PrivateKey }
|
||||||
|
|
||||||
|
// RSA1024KeyFromBlob creates a RSAKey for the given response blob.
|
||||||
|
func RSA1024KeyFromBlob(blob string) (*RSAKey, error) {
|
||||||
|
byts, err := base64.StdEncoding.DecodeString(blob)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
rsaKey, err := x509.ParsePKCS1PrivateKey(byts)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &RSAKey{rsaKey}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Type implements Key.Type.
|
||||||
|
func (*RSAKey) Type() KeyType { return KeyTypeRSA1024 }
|
||||||
|
|
||||||
|
// Blob implements Key.Blob.
|
||||||
|
func (r *RSAKey) Blob() string {
|
||||||
|
return base64.StdEncoding.EncodeToString(x509.MarshalPKCS1PrivateKey(r.PrivateKey))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ED25519Key is a Key for AddOnion that is a ed25519 key (i.e. v3).
|
||||||
|
type ED25519Key struct{ ed25519.KeyPair }
|
||||||
|
|
||||||
|
// ED25519KeyFromBlob creates a ED25519Key for the given response blob.
|
||||||
|
func ED25519KeyFromBlob(blob string) (*ED25519Key, error) {
|
||||||
|
byts, err := base64.StdEncoding.DecodeString(blob)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &ED25519Key{ed25519.PrivateKey(byts).KeyPair()}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Type implements Key.Type.
|
||||||
|
func (*ED25519Key) Type() KeyType { return KeyTypeED25519V3 }
|
||||||
|
|
||||||
|
// Blob implements Key.Blob.
|
||||||
|
func (e *ED25519Key) Blob() string { return base64.StdEncoding.EncodeToString(e.PrivateKey()) }
|
||||||
|
|
||||||
|
// AddOnionRequest is a set of request params for AddOnion.
|
||||||
|
type AddOnionRequest struct {
|
||||||
|
// Key is the key to use or GenKey if Tor should generate it.
|
||||||
|
Key Key
|
||||||
|
// Flags are ADD_ONION flags.
|
||||||
|
Flags []string
|
||||||
|
// MaxStreams is ADD_ONION MaxStreams.
|
||||||
|
MaxStreams int
|
||||||
|
// Ports are ADD_ONION Port values. Key is virtual port, Val is target
|
||||||
|
// port (or can be empty to use virtual port).
|
||||||
|
Ports []*KeyVal
|
||||||
|
// ClientAuths are ADD_ONION ClientAuth values. If value is empty string,
|
||||||
|
// Tor will generate the password.
|
||||||
|
ClientAuths map[string]string
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddOnionResponse is the response for AddOnion.
|
||||||
|
type AddOnionResponse struct {
|
||||||
|
// ServiceID is the ADD_ONION response ServiceID value.
|
||||||
|
ServiceID string
|
||||||
|
// Key is the ADD_ONION response PrivateKey value.
|
||||||
|
Key Key
|
||||||
|
// ClientAuths are the ADD_ONION response ClientAuth values.
|
||||||
|
ClientAuths map[string]string
|
||||||
|
// RawResponse is the raw ADD_ONION response.
|
||||||
|
RawResponse *Response
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddOnion invokes ADD_ONION and returns its response.
|
||||||
|
func (c *Conn) AddOnion(req *AddOnionRequest) (*AddOnionResponse, error) {
|
||||||
|
// Build command
|
||||||
|
if req.Key == nil {
|
||||||
|
return nil, c.protoErr("Key required")
|
||||||
|
}
|
||||||
|
cmd := "ADD_ONION " + string(req.Key.Type()) + ":" + req.Key.Blob()
|
||||||
|
if len(req.Flags) > 0 {
|
||||||
|
cmd += " Flags=" + strings.Join(req.Flags, ",")
|
||||||
|
}
|
||||||
|
if req.MaxStreams > 0 {
|
||||||
|
cmd += " MaxStreams=" + strconv.Itoa(req.MaxStreams)
|
||||||
|
}
|
||||||
|
for _, port := range req.Ports {
|
||||||
|
cmd += " Port=" + port.Key
|
||||||
|
if port.Val != "" {
|
||||||
|
cmd += "," + port.Val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for name, blob := range req.ClientAuths {
|
||||||
|
cmd += " ClientAuth=" + name
|
||||||
|
if blob != "" {
|
||||||
|
cmd += ":" + blob
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Invoke and read response
|
||||||
|
resp, err := c.SendRequest(cmd)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
ret := &AddOnionResponse{RawResponse: resp}
|
||||||
|
for _, data := range resp.Data {
|
||||||
|
key, val, _ := torutil.PartitionString(data, '=')
|
||||||
|
switch key {
|
||||||
|
case "ServiceID":
|
||||||
|
ret.ServiceID = val
|
||||||
|
case "PrivateKey":
|
||||||
|
if ret.Key, err = KeyFromString(val); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
case "ClientAuth":
|
||||||
|
name, pass, _ := torutil.PartitionString(val, ':')
|
||||||
|
if ret.ClientAuths == nil {
|
||||||
|
ret.ClientAuths = map[string]string{}
|
||||||
|
}
|
||||||
|
ret.ClientAuths[name] = pass
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DelOnion invokes DELONION.
|
||||||
|
func (c *Conn) DelOnion(serviceID string) error {
|
||||||
|
return c.sendRequestIgnoreResponse("DEL_ONION %v", serviceID)
|
||||||
|
}
|
76
vendor/github.com/cretz/bine/control/cmd_protocolinfo.go
generated
vendored
Normal file
76
vendor/github.com/cretz/bine/control/cmd_protocolinfo.go
generated
vendored
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
package control
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/cretz/bine/torutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ProtocolInfo is the protocol info result of Conn.ProtocolInfo.
|
||||||
|
type ProtocolInfo struct {
|
||||||
|
AuthMethods []string
|
||||||
|
CookieFile string
|
||||||
|
TorVersion string
|
||||||
|
RawResponse *Response
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasAuthMethod checks if ProtocolInfo contains the requested auth method.
|
||||||
|
func (p *ProtocolInfo) HasAuthMethod(authMethod string) bool {
|
||||||
|
for _, m := range p.AuthMethods {
|
||||||
|
if m == authMethod {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// ProtocolInfo invokes PROTOCOLINFO on first invocation and returns a cached
|
||||||
|
// result on all others.
|
||||||
|
func (c *Conn) ProtocolInfo() (*ProtocolInfo, error) {
|
||||||
|
var err error
|
||||||
|
if c.protocolInfo == nil {
|
||||||
|
c.protocolInfo, err = c.sendProtocolInfo()
|
||||||
|
}
|
||||||
|
return c.protocolInfo, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Conn) sendProtocolInfo() (*ProtocolInfo, error) {
|
||||||
|
resp, err := c.SendRequest("PROTOCOLINFO")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// Check data vals
|
||||||
|
ret := &ProtocolInfo{RawResponse: resp}
|
||||||
|
for _, piece := range resp.Data {
|
||||||
|
key, val, ok := torutil.PartitionString(piece, ' ')
|
||||||
|
if !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
switch key {
|
||||||
|
case "PROTOCOLINFO":
|
||||||
|
if val != "1" {
|
||||||
|
return nil, c.protoErr("Invalid PIVERSION: %v", val)
|
||||||
|
}
|
||||||
|
case "AUTH":
|
||||||
|
methods, cookieFile, _ := torutil.PartitionString(val, ' ')
|
||||||
|
if !strings.HasPrefix(methods, "METHODS=") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if cookieFile != "" {
|
||||||
|
if !strings.HasPrefix(cookieFile, "COOKIEFILE=") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if ret.CookieFile, err = torutil.UnescapeSimpleQuotedString(cookieFile[11:]); err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ret.AuthMethods = strings.Split(methods[8:], ",")
|
||||||
|
case "VERSION":
|
||||||
|
torVersion, _, _ := torutil.PartitionString(val, ' ')
|
||||||
|
if strings.HasPrefix(torVersion, "Tor=") {
|
||||||
|
ret.TorVersion, err = torutil.UnescapeSimpleQuotedString(torVersion[4:])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret, nil
|
||||||
|
}
|
31
vendor/github.com/cretz/bine/control/cmd_stream.go
generated
vendored
Normal file
31
vendor/github.com/cretz/bine/control/cmd_stream.go
generated
vendored
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
package control
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
// AttachStream invokes ATTACHSTREAM.
|
||||||
|
func (c *Conn) AttachStream(streamID string, circuitID string, hopNum int) error {
|
||||||
|
if circuitID == "" {
|
||||||
|
circuitID = "0"
|
||||||
|
}
|
||||||
|
cmd := "ATTACHSTREAM " + streamID + " " + circuitID
|
||||||
|
if hopNum > 0 {
|
||||||
|
cmd += " HOP=" + strconv.Itoa(hopNum)
|
||||||
|
}
|
||||||
|
return c.sendRequestIgnoreResponse(cmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RedirectStream invokes REDIRECTSTREAM.
|
||||||
|
func (c *Conn) RedirectStream(streamID string, address string, port int) error {
|
||||||
|
cmd := "REDIRECTSTREAM " + streamID + " " + address
|
||||||
|
if port > 0 {
|
||||||
|
cmd += " " + strconv.Itoa(port)
|
||||||
|
}
|
||||||
|
return c.sendRequestIgnoreResponse(cmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CloseStream invokes CLOSESTREAM.
|
||||||
|
func (c *Conn) CloseStream(streamID string, reason string) error {
|
||||||
|
return c.sendRequestIgnoreResponse("CLOSESTREAM %v %v", streamID, reason)
|
||||||
|
}
|
102
vendor/github.com/cretz/bine/control/conn.go
generated
vendored
Normal file
102
vendor/github.com/cretz/bine/control/conn.go
generated
vendored
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
package control
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net/textproto"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Conn is the connection to the Tor control port.
|
||||||
|
type Conn struct {
|
||||||
|
// DebugWriter is the writer that debug logs for this library (not Tor
|
||||||
|
// itself) will be written to. If nil, no debug logs are generated/written.
|
||||||
|
DebugWriter io.Writer
|
||||||
|
|
||||||
|
// This is the underlying connection.
|
||||||
|
conn *textproto.Conn
|
||||||
|
|
||||||
|
// This is set lazily by ProtocolInfo().
|
||||||
|
protocolInfo *ProtocolInfo
|
||||||
|
|
||||||
|
// True if Authenticate has been called successfully.
|
||||||
|
Authenticated bool
|
||||||
|
|
||||||
|
// The lock fot eventListeners
|
||||||
|
eventListenersLock sync.RWMutex
|
||||||
|
// The value slices can be traversed outside of lock, they are completely
|
||||||
|
// replaced on change, never mutated. But the map itself must be locked on
|
||||||
|
// when reading or writing.
|
||||||
|
eventListeners map[EventCode][]chan<- Event
|
||||||
|
|
||||||
|
// This mutex is locked on when an entire response needs to be read. It
|
||||||
|
// helps synchronize accesses to the response by the asynchronous response
|
||||||
|
// listeners and the synchronous responses.
|
||||||
|
readLock sync.Mutex
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewConn creates a Conn from the given textproto connection.
|
||||||
|
func NewConn(conn *textproto.Conn) *Conn {
|
||||||
|
return &Conn{
|
||||||
|
conn: conn,
|
||||||
|
eventListeners: map[EventCode][]chan<- Event{},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Conn) sendRequestIgnoreResponse(format string, args ...interface{}) error {
|
||||||
|
_, err := c.SendRequest(format, args...)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// SendRequest sends a synchronous request to Tor and awaits the response. If
|
||||||
|
// the response errors, the error result will be set, but the response will be
|
||||||
|
// set also. This is usually not directly used by callers, but instead called by
|
||||||
|
// higher-level methods.
|
||||||
|
func (c *Conn) SendRequest(format string, args ...interface{}) (*Response, error) {
|
||||||
|
if c.debugEnabled() {
|
||||||
|
c.debugf("Write line: %v", fmt.Sprintf(format, args...))
|
||||||
|
}
|
||||||
|
id, err := c.conn.Cmd(format, args...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
c.readLock.Lock()
|
||||||
|
defer c.readLock.Unlock()
|
||||||
|
c.conn.StartResponse(id)
|
||||||
|
defer c.conn.EndResponse(id)
|
||||||
|
// Get the first non-async response
|
||||||
|
var resp *Response
|
||||||
|
for {
|
||||||
|
if resp, err = c.ReadResponse(); err != nil || !resp.IsAsync() {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
c.relayAsyncEvents(resp)
|
||||||
|
}
|
||||||
|
if err == nil && !resp.IsOk() {
|
||||||
|
err = resp.Err
|
||||||
|
}
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close sends a QUIT and closes the underlying Tor connection. This does not
|
||||||
|
// error if the QUIT is not accepted but does relay any error that occurs while
|
||||||
|
// closing the underlying connection.
|
||||||
|
func (c *Conn) Close() error {
|
||||||
|
// Ignore the response and ignore the error
|
||||||
|
c.Quit()
|
||||||
|
return c.conn.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Conn) debugEnabled() bool {
|
||||||
|
return c.DebugWriter != nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Conn) debugf(format string, args ...interface{}) {
|
||||||
|
if w := c.DebugWriter; w != nil {
|
||||||
|
fmt.Fprintf(w, format+"\n", args...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*Conn) protoErr(format string, args ...interface{}) textproto.ProtocolError {
|
||||||
|
return textproto.ProtocolError(fmt.Sprintf(format, args...))
|
||||||
|
}
|
10
vendor/github.com/cretz/bine/control/doc.go
generated
vendored
Normal file
10
vendor/github.com/cretz/bine/control/doc.go
generated
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
// Package control implements a low-level client for the Tor control spec
|
||||||
|
// version 1.
|
||||||
|
//
|
||||||
|
// The primary entrypoint is the Conn struct, instantiated with NewConn. This is
|
||||||
|
// the low-level layer to the control port of an already-running Tor instance.
|
||||||
|
// Most developers will prefer the tor package adjacent to this one for a higher
|
||||||
|
// level abstraction over the process and this connection.
|
||||||
|
//
|
||||||
|
// Some of this code is lifted from https://github.com/yawning/bulb with thanks.
|
||||||
|
package control
|
40
vendor/github.com/cretz/bine/control/keyval.go
generated
vendored
Normal file
40
vendor/github.com/cretz/bine/control/keyval.go
generated
vendored
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
package control
|
||||||
|
|
||||||
|
// KeyVal is a simple key-value struct. In cases where Val can be nil, an empty
|
||||||
|
// string represents that unless ValSetAndEmpty is true.
|
||||||
|
type KeyVal struct {
|
||||||
|
// Key is the always-present key
|
||||||
|
Key string
|
||||||
|
|
||||||
|
// Val is the value. If it's an empty string and nils are accepted/supported
|
||||||
|
// where this is used, it means nil unless ValSetAndEmpty is true.
|
||||||
|
Val string
|
||||||
|
|
||||||
|
// ValSetAndEmpty is true when Val is an empty string, the associated
|
||||||
|
// command supports nils, and Val should NOT be treated as nil. False
|
||||||
|
// otherwise.
|
||||||
|
ValSetAndEmpty bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewKeyVal creates a new key-value pair.
|
||||||
|
func NewKeyVal(key string, val string) *KeyVal {
|
||||||
|
return &KeyVal{Key: key, Val: val}
|
||||||
|
}
|
||||||
|
|
||||||
|
// KeyVals creates multiple new key-value pairs from the given strings. The
|
||||||
|
// provided set of strings must have a length that is a multiple of 2.
|
||||||
|
func KeyVals(keysAndVals ...string) []*KeyVal {
|
||||||
|
if len(keysAndVals)%2 != 0 {
|
||||||
|
panic("Expected multiple of 2")
|
||||||
|
}
|
||||||
|
ret := make([]*KeyVal, len(keysAndVals)/2)
|
||||||
|
for i := 0; i < len(ret); i++ {
|
||||||
|
ret[i] = NewKeyVal(keysAndVals[i*2], keysAndVals[i*2+1])
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValSet returns true if Val is either non empty or ValSetAndEmpty is true.
|
||||||
|
func (k *KeyVal) ValSet() bool {
|
||||||
|
return len(k.Val) > 0 || k.ValSetAndEmpty
|
||||||
|
}
|
106
vendor/github.com/cretz/bine/control/response.go
generated
vendored
Normal file
106
vendor/github.com/cretz/bine/control/response.go
generated
vendored
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
package control
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/textproto"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Response is a response to a control port command or an asynchronous event.
|
||||||
|
type Response struct {
|
||||||
|
// Err is the status code and string representation associated with a
|
||||||
|
// response. Responses that have completed successfully will also have Err
|
||||||
|
// set to indicate such.
|
||||||
|
Err *textproto.Error
|
||||||
|
|
||||||
|
// Reply is the text on the EndReplyLine of the response.
|
||||||
|
Reply string
|
||||||
|
|
||||||
|
// Data is the MidReplyLines/DataReplyLines of the response. Dot encoded
|
||||||
|
// data is "decoded" and presented as a single string (terminal ".CRLF"
|
||||||
|
// removed, all intervening CRs stripped).
|
||||||
|
Data []string
|
||||||
|
|
||||||
|
// RawLines is all of the lines of a response, without CRLFs.
|
||||||
|
RawLines []string
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsOk returns true if the response status code indicates success or an
|
||||||
|
// asynchronous event.
|
||||||
|
func (r *Response) IsOk() bool {
|
||||||
|
switch r.Err.Code {
|
||||||
|
case StatusOk, StatusOkUnnecessary, StatusAsyncEvent:
|
||||||
|
return true
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DataWithReply returns a combination of Data and Reply to give a full set of
|
||||||
|
// the lines of the response.
|
||||||
|
func (r *Response) DataWithReply() []string {
|
||||||
|
ret := make([]string, len(r.Data)+1)
|
||||||
|
copy(ret, r.Data)
|
||||||
|
ret[len(ret)-1] = r.Reply
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsAsync returns true if the response is an asynchronous event.
|
||||||
|
func (r *Response) IsAsync() bool {
|
||||||
|
return r.Err.Code == StatusAsyncEvent
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReadResponse returns the next response object.
|
||||||
|
func (c *Conn) ReadResponse() (*Response, error) {
|
||||||
|
var resp *Response
|
||||||
|
var statusCode int
|
||||||
|
for {
|
||||||
|
line, err := c.conn.ReadLine()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
c.debugf("Read line: %v", line)
|
||||||
|
|
||||||
|
// Parse the line that was just read.
|
||||||
|
if len(line) < 4 {
|
||||||
|
return nil, c.protoErr("Truncated response: %v", line)
|
||||||
|
}
|
||||||
|
if code, err := strconv.Atoi(line[0:3]); err != nil || code < 100 {
|
||||||
|
return nil, c.protoErr("Invalid status code: %v", line[0:3])
|
||||||
|
} else if resp == nil {
|
||||||
|
resp = &Response{}
|
||||||
|
statusCode = code
|
||||||
|
} else if code != statusCode {
|
||||||
|
// The status code should stay fixed for all lines of the response, since events can't be interleaved with
|
||||||
|
// response lines.
|
||||||
|
return nil, c.protoErr("Status code changed: %v != %v", code, statusCode)
|
||||||
|
}
|
||||||
|
resp.RawLines = append(resp.RawLines, line)
|
||||||
|
switch line[3] {
|
||||||
|
case ' ':
|
||||||
|
// Final line in the response.
|
||||||
|
resp.Reply = line[4:]
|
||||||
|
resp.Err = statusCodeToError(statusCode, resp.Reply)
|
||||||
|
return resp, nil
|
||||||
|
case '-':
|
||||||
|
// Continuation, keep reading.
|
||||||
|
resp.Data = append(resp.Data, line[4:])
|
||||||
|
case '+':
|
||||||
|
// A "dot-encoded" payload follows.
|
||||||
|
dotBody, err := c.conn.ReadDotBytes()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
dotBodyStr := strings.TrimRight(string(dotBody), "\n\r")
|
||||||
|
// c.debugf("Read dot body:\n---\n%v\n---", dotBodyStr)
|
||||||
|
resp.Data = append(resp.Data, line[4:]+"\r\n"+dotBodyStr)
|
||||||
|
dotLines := strings.Split(dotBodyStr, "\n")
|
||||||
|
for _, dotLine := range dotLines[:len(dotLines)-1] {
|
||||||
|
resp.RawLines = append(resp.RawLines, dotLine)
|
||||||
|
}
|
||||||
|
resp.RawLines = append(resp.RawLines, ".")
|
||||||
|
default:
|
||||||
|
return nil, c.protoErr("Invalid separator: '%v'", line[3])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
64
vendor/github.com/cretz/bine/control/status.go
generated
vendored
Normal file
64
vendor/github.com/cretz/bine/control/status.go
generated
vendored
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
package control
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/textproto"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// The various control port StatusCode constants.
|
||||||
|
const (
|
||||||
|
StatusOk = 250
|
||||||
|
StatusOkUnnecessary = 251
|
||||||
|
|
||||||
|
StatusErrResourceExhausted = 451
|
||||||
|
StatusErrSyntaxError = 500
|
||||||
|
StatusErrUnrecognizedCmd = 510
|
||||||
|
StatusErrUnimplementedCmd = 511
|
||||||
|
StatusErrSyntaxErrorArg = 512
|
||||||
|
StatusErrUnrecognizedCmdArg = 513
|
||||||
|
StatusErrAuthenticationRequired = 514
|
||||||
|
StatusErrBadAuthentication = 515
|
||||||
|
StatusErrUnspecifiedTorError = 550
|
||||||
|
StatusErrInternalError = 551
|
||||||
|
StatusErrUnrecognizedEntity = 552
|
||||||
|
StatusErrInvalidConfigValue = 553
|
||||||
|
StatusErrInvalidDescriptor = 554
|
||||||
|
StatusErrUnmanagedEntity = 555
|
||||||
|
|
||||||
|
StatusAsyncEvent = 650
|
||||||
|
)
|
||||||
|
|
||||||
|
var statusCodeStringMap = map[int]string{
|
||||||
|
StatusOk: "OK",
|
||||||
|
StatusOkUnnecessary: "Operation was unnecessary",
|
||||||
|
|
||||||
|
StatusErrResourceExhausted: "Resource exhausted",
|
||||||
|
StatusErrSyntaxError: "Syntax error: protocol",
|
||||||
|
StatusErrUnrecognizedCmd: "Unrecognized command",
|
||||||
|
StatusErrUnimplementedCmd: "Unimplemented command",
|
||||||
|
StatusErrSyntaxErrorArg: "Syntax error in command argument",
|
||||||
|
StatusErrUnrecognizedCmdArg: "Unrecognized command argument",
|
||||||
|
StatusErrAuthenticationRequired: "Authentication required",
|
||||||
|
StatusErrBadAuthentication: "Bad authentication",
|
||||||
|
StatusErrUnspecifiedTorError: "Unspecified Tor error",
|
||||||
|
StatusErrInternalError: "Internal error",
|
||||||
|
StatusErrUnrecognizedEntity: "Unrecognized entity",
|
||||||
|
StatusErrInvalidConfigValue: "Invalid configuration value",
|
||||||
|
StatusErrInvalidDescriptor: "Invalid descriptor",
|
||||||
|
StatusErrUnmanagedEntity: "Unmanaged entity",
|
||||||
|
|
||||||
|
StatusAsyncEvent: "Asynchronous event notification",
|
||||||
|
}
|
||||||
|
|
||||||
|
func statusCodeToError(code int, reply string) *textproto.Error {
|
||||||
|
err := new(textproto.Error)
|
||||||
|
err.Code = code
|
||||||
|
if msg, ok := statusCodeStringMap[code]; ok {
|
||||||
|
trimmedReply := strings.TrimSpace(strings.TrimPrefix(reply, msg))
|
||||||
|
err.Msg = fmt.Sprintf("%s: %s", msg, trimmedReply)
|
||||||
|
} else {
|
||||||
|
err.Msg = fmt.Sprintf("Unknown status code (%03d): %s", code, reply)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
81
vendor/github.com/cretz/bine/process/process.go
generated
vendored
Normal file
81
vendor/github.com/cretz/bine/process/process.go
generated
vendored
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
// Package process is the low-level abstraction for a Tor instance.
|
||||||
|
//
|
||||||
|
// The standard use is to create a Creator with NewCreator and the path to the
|
||||||
|
// Tor executable. The child package 'embedded' can be used if Tor is statically
|
||||||
|
// linked in the binary. Most developers will prefer the tor package adjacent to
|
||||||
|
// this one for a higher level abstraction over the process and control port
|
||||||
|
// connection.
|
||||||
|
package process
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/cretz/bine/torutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Process is the interface implemented by Tor processes.
|
||||||
|
type Process interface {
|
||||||
|
// Start starts the Tor process in the background and returns. It is
|
||||||
|
// analagous to os/exec.Cmd.Start.
|
||||||
|
Start() error
|
||||||
|
// Wait waits for the Tor process to exit and returns error if it was not a
|
||||||
|
// successful exit. It is analagous to os/exec.Cmd.Wait.
|
||||||
|
Wait() error
|
||||||
|
// ControlConn is used for statically linked, embedded processes to create
|
||||||
|
// a controller connection. For non-embedded processes or Tor versions that
|
||||||
|
// don't support embedded control connections, ErrControlConnUnsupported is
|
||||||
|
// returned. Note, this should only be called once per process before
|
||||||
|
// Start, and the connection does not need to be closed.
|
||||||
|
EmbeddedControlConn() (net.Conn, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creator is the interface for process creation.
|
||||||
|
type Creator interface {
|
||||||
|
New(ctx context.Context, args ...string) (Process, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type exeProcessCreator struct {
|
||||||
|
exePath string
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewCreator creates a Creator for external Tor process execution based on the
|
||||||
|
// given exe path.
|
||||||
|
func NewCreator(exePath string) Creator {
|
||||||
|
return &exeProcessCreator{exePath}
|
||||||
|
}
|
||||||
|
|
||||||
|
type exeProcess struct {
|
||||||
|
*exec.Cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *exeProcessCreator) New(ctx context.Context, args ...string) (Process, error) {
|
||||||
|
cmd := exec.CommandContext(ctx, e.exePath, args...)
|
||||||
|
cmd.Stdout = os.Stdout
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
return &exeProcess{cmd}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ErrControlConnUnsupported is returned by Process.EmbeddedControlConn when
|
||||||
|
// it is unsupported.
|
||||||
|
var ErrControlConnUnsupported = fmt.Errorf("Control conn not supported")
|
||||||
|
|
||||||
|
func (e *exeProcess) EmbeddedControlConn() (net.Conn, error) {
|
||||||
|
return nil, ErrControlConnUnsupported
|
||||||
|
}
|
||||||
|
|
||||||
|
// ControlPortFromFileContents reads a control port file that is written by Tor
|
||||||
|
// when ControlPortWriteToFile is set.
|
||||||
|
func ControlPortFromFileContents(contents string) (int, error) {
|
||||||
|
contents = strings.TrimSpace(contents)
|
||||||
|
_, port, ok := torutil.PartitionString(contents, ':')
|
||||||
|
if !ok || !strings.HasPrefix(contents, "PORT=") {
|
||||||
|
return 0, fmt.Errorf("Invalid port format: %v", contents)
|
||||||
|
}
|
||||||
|
return strconv.Atoi(port)
|
||||||
|
}
|
111
vendor/github.com/cretz/bine/tor/dialer.go
generated
vendored
Normal file
111
vendor/github.com/cretz/bine/tor/dialer.go
generated
vendored
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
package tor
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"golang.org/x/net/proxy"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Dialer is a wrapper around a proxy.Dialer for dialing connections.
|
||||||
|
type Dialer struct {
|
||||||
|
proxy.Dialer
|
||||||
|
}
|
||||||
|
|
||||||
|
// DialConf is the configuration used for Dialer.
|
||||||
|
type DialConf struct {
|
||||||
|
// ProxyAddress is the address for the SOCKS5 proxy. If empty, it is looked
|
||||||
|
// up.
|
||||||
|
ProxyAddress string
|
||||||
|
|
||||||
|
// ProxyNetwork is the network for the SOCKS5 proxy. If ProxyAddress is
|
||||||
|
// empty, this value is ignored and overridden by what is looked up. If this
|
||||||
|
// is empty and ProxyAddress is not empty, it defaults to "tcp".
|
||||||
|
ProxyNetwork string
|
||||||
|
|
||||||
|
// ProxyAuth is the auth for the proxy. Since Tor's SOCKS5 proxy is
|
||||||
|
// unauthenticated, this is rarely needed. It can be used when
|
||||||
|
// IsolateSOCKSAuth is set to ensure separate circuits.
|
||||||
|
//
|
||||||
|
// This should not be confused with downstream SOCKS proxy authentication
|
||||||
|
// which is set via Tor values for Socks5ProxyUsername and
|
||||||
|
// Socks5ProxyPassword when Socks5Proxy is set.
|
||||||
|
ProxyAuth *proxy.Auth
|
||||||
|
|
||||||
|
// SkipEnableNetwork, if true, will skip the enable network step in Dialer.
|
||||||
|
SkipEnableNetwork bool
|
||||||
|
|
||||||
|
// Forward is the dialer to forward to. If nil, just uses normal net dialer.
|
||||||
|
Forward proxy.Dialer
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dialer creates a new Dialer for the given configuration. Context can be nil.
|
||||||
|
// If conf is nil, a default is used.
|
||||||
|
func (t *Tor) Dialer(ctx context.Context, conf *DialConf) (*Dialer, error) {
|
||||||
|
if ctx == nil {
|
||||||
|
ctx = context.Background()
|
||||||
|
}
|
||||||
|
if conf == nil {
|
||||||
|
conf = &DialConf{}
|
||||||
|
}
|
||||||
|
// Enable the network if requested
|
||||||
|
if !conf.SkipEnableNetwork {
|
||||||
|
if err := t.EnableNetwork(ctx, true); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Lookup proxy address as needed
|
||||||
|
proxyNetwork := conf.ProxyNetwork
|
||||||
|
proxyAddress := conf.ProxyAddress
|
||||||
|
if proxyAddress == "" {
|
||||||
|
info, err := t.Control.GetInfo("net/listeners/socks")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if len(info) != 1 || info[0].Key != "net/listeners/socks" {
|
||||||
|
return nil, fmt.Errorf("Unable to get socks proxy address")
|
||||||
|
}
|
||||||
|
proxyAddress = info[0].Val
|
||||||
|
if strings.HasPrefix(proxyAddress, "unix:") {
|
||||||
|
proxyAddress = proxyAddress[5:]
|
||||||
|
proxyNetwork = "unix"
|
||||||
|
} else {
|
||||||
|
proxyNetwork = "tcp"
|
||||||
|
}
|
||||||
|
} else if proxyNetwork == "" {
|
||||||
|
proxyNetwork = "tcp"
|
||||||
|
}
|
||||||
|
|
||||||
|
dialer, err := proxy.SOCKS5(proxyNetwork, proxyAddress, conf.ProxyAuth, conf.Forward)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &Dialer{dialer}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DialContext is the equivalent of net.DialContext.
|
||||||
|
//
|
||||||
|
// TODO: Remove when https://github.com/golang/go/issues/17759 is released.
|
||||||
|
func (d *Dialer) DialContext(ctx context.Context, network string, addr string) (net.Conn, error) {
|
||||||
|
errCh := make(chan error, 1)
|
||||||
|
connCh := make(chan net.Conn, 1)
|
||||||
|
go func() {
|
||||||
|
if conn, err := d.Dial(network, addr); err != nil {
|
||||||
|
errCh <- err
|
||||||
|
} else if ctx.Err() != nil {
|
||||||
|
conn.Close()
|
||||||
|
} else {
|
||||||
|
connCh <- conn
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
select {
|
||||||
|
case err := <-errCh:
|
||||||
|
return nil, err
|
||||||
|
case conn := <-connCh:
|
||||||
|
return conn, nil
|
||||||
|
case <-ctx.Done():
|
||||||
|
return nil, ctx.Err()
|
||||||
|
}
|
||||||
|
}
|
7
vendor/github.com/cretz/bine/tor/doc.go
generated
vendored
Normal file
7
vendor/github.com/cretz/bine/tor/doc.go
generated
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
// Package tor is the high-level client for Tor.
|
||||||
|
//
|
||||||
|
// The Tor type is a combination of a Tor instance and a connection to it.
|
||||||
|
// Use Start to create Tor. Then Dialer or Listener can be used.
|
||||||
|
//
|
||||||
|
// Some of this code is lifted from https://github.com/yawning/bulb with thanks.
|
||||||
|
package tor
|
343
vendor/github.com/cretz/bine/tor/listen.go
generated
vendored
Normal file
343
vendor/github.com/cretz/bine/tor/listen.go
generated
vendored
Normal file
@ -0,0 +1,343 @@
|
|||||||
|
package tor
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"crypto"
|
||||||
|
"crypto/rsa"
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/cretz/bine/control"
|
||||||
|
"github.com/cretz/bine/torutil/ed25519"
|
||||||
|
othered25519 "golang.org/x/crypto/ed25519"
|
||||||
|
)
|
||||||
|
|
||||||
|
// OnionService implements net.Listener and net.Addr for an onion service.
|
||||||
|
type OnionService struct {
|
||||||
|
// ID is the service ID for this onion service.
|
||||||
|
ID string
|
||||||
|
|
||||||
|
// Key is the private key for this service. It is either the set key, the
|
||||||
|
// generated key, or nil if asked to discard the key. If present, it is
|
||||||
|
// *crypto/rsa.PrivateKey (1024 bit) when Version3 is false or
|
||||||
|
// github.com/cretz/bine/torutil/ed25519.KeyPair when Version3 is true.
|
||||||
|
Key crypto.PrivateKey
|
||||||
|
|
||||||
|
// Version3 says whether or not this service is a V3 service.
|
||||||
|
Version3 bool
|
||||||
|
|
||||||
|
// ClientAuths is the credential set for clients. The keys are username and
|
||||||
|
// the values are credentials. The credentials will always be present even
|
||||||
|
// if Tor had to generate them.
|
||||||
|
ClientAuths map[string]string
|
||||||
|
|
||||||
|
// LocalListener is the local TCP listener. This is always present.
|
||||||
|
LocalListener net.Listener
|
||||||
|
|
||||||
|
// RemotePorts is the set of remote ports that are forwarded to the local
|
||||||
|
// listener. This will always have at least one value.
|
||||||
|
RemotePorts []int
|
||||||
|
|
||||||
|
// CloseLocalListenerOnClose is true if the local listener should be closed
|
||||||
|
// on Close. This is set to true if a listener was created by Listen and set
|
||||||
|
// to false of an existing LocalListener was provided to Listen.
|
||||||
|
CloseLocalListenerOnClose bool
|
||||||
|
|
||||||
|
// The Tor object that created this. Needed for Close.
|
||||||
|
Tor *Tor
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListenConf is the configuration for Listen calls.
|
||||||
|
type ListenConf struct {
|
||||||
|
// LocalPort is the local port to create a TCP listener on. If the port is
|
||||||
|
// 0, it is automatically chosen. This is ignored if LocalListener is set.
|
||||||
|
LocalPort int
|
||||||
|
|
||||||
|
// LocalListener is the specific local listener to back the onion service.
|
||||||
|
// If this is nil (the default), then a listener is created with LocalPort.
|
||||||
|
LocalListener net.Listener
|
||||||
|
|
||||||
|
// RemotePorts are the remote ports to serve the onion service on. If empty,
|
||||||
|
// it is the same as the local port or local listener. This must have at
|
||||||
|
// least one value if the local listener is not a *net.TCPListener.
|
||||||
|
RemotePorts []int
|
||||||
|
|
||||||
|
// Key is the private key to use. If not present, a key is generated based
|
||||||
|
// on whether Version3 is true or false. If present, it must be a
|
||||||
|
// *crypto/rsa.PrivateKey (1024 bit), a
|
||||||
|
// github.com/cretz/bine/torutil/ed25519.KeyPair, a
|
||||||
|
// golang.org/x/crypto/ed25519.PrivateKey, or a
|
||||||
|
// github.com/cretz/bine/control.Key.
|
||||||
|
Key crypto.PrivateKey
|
||||||
|
|
||||||
|
// Version3 determines whether, when Key is nil, a version 2 or version 3
|
||||||
|
// service/key will be generated. If true it is version 3 (an ed25519 key
|
||||||
|
// and v3 onion service) and if false it is version 2 (a RSA-1024 key and v2
|
||||||
|
// onion service). If Key is not nil, this value is ignored.
|
||||||
|
Version3 bool
|
||||||
|
|
||||||
|
// ClientAuths is the set of usernames and credentials for client
|
||||||
|
// authentication. The keys are usernames and the values are credentials. If
|
||||||
|
// a username is present but the credential is empty, a credential is
|
||||||
|
// generated by Tor for that user. If this is empty there is no
|
||||||
|
// authentication.
|
||||||
|
ClientAuths map[string]string
|
||||||
|
|
||||||
|
// MaxStreams is the maximum number of streams the service will accept. 0
|
||||||
|
// means unlimited.
|
||||||
|
MaxStreams int
|
||||||
|
|
||||||
|
// DiscardKey, if true and Key is nil (meaning a private key is generated),
|
||||||
|
// tells Tor not to return the generated private key. This value is ignored
|
||||||
|
// if Key is not nil.
|
||||||
|
DiscardKey bool
|
||||||
|
|
||||||
|
// Detach, if true, prevents the default behavior of the onion service being
|
||||||
|
// deleted when this controller connection is closed.
|
||||||
|
Detach bool
|
||||||
|
|
||||||
|
// NonAnonymous must be true if Tor options HiddenServiceSingleHopMode and
|
||||||
|
// HiddenServiceNonAnonymousMode are set. Otherwise, it must be false.
|
||||||
|
NonAnonymous bool
|
||||||
|
|
||||||
|
// MaxStreamsCloseCircuit determines whether to close the circuit when the
|
||||||
|
// maximum number of streams is exceeded. If true, the circuit is closed. If
|
||||||
|
// false, the stream is simply not connected but the circuit stays open.
|
||||||
|
MaxStreamsCloseCircuit bool
|
||||||
|
|
||||||
|
// NoWait if true will not wait until the onion service is published. If
|
||||||
|
// false, the network will be enabled if it's not and then we will wait
|
||||||
|
// until the onion service is published.
|
||||||
|
NoWait bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// Listen creates an onion service and local listener. The context can be nil.
|
||||||
|
// If conf is nil, the default struct value is used. Note, if this errors, any
|
||||||
|
// listeners created here are closed but if a LocalListener is provided it may remain open.
|
||||||
|
func (t *Tor) Listen(ctx context.Context, conf *ListenConf) (*OnionService, error) {
|
||||||
|
if ctx == nil {
|
||||||
|
ctx = context.Background()
|
||||||
|
}
|
||||||
|
// Create the service up here and make sure we close it no matter the error within
|
||||||
|
svc := &OnionService{Tor: t, CloseLocalListenerOnClose: conf.LocalListener == nil}
|
||||||
|
var err error
|
||||||
|
|
||||||
|
// Create the local listener if necessary
|
||||||
|
svc.LocalListener = conf.LocalListener
|
||||||
|
if svc.LocalListener == nil {
|
||||||
|
if svc.LocalListener, err = net.Listen("tcp", "127.0.0.1:"+strconv.Itoa(conf.LocalPort)); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Henceforth, any error requires we close the svc
|
||||||
|
|
||||||
|
// Build the onion request
|
||||||
|
req := &control.AddOnionRequest{MaxStreams: conf.MaxStreams, ClientAuths: conf.ClientAuths}
|
||||||
|
// Set flags
|
||||||
|
if conf.DiscardKey {
|
||||||
|
req.Flags = append(req.Flags, "DiscardPK")
|
||||||
|
}
|
||||||
|
if conf.Detach {
|
||||||
|
req.Flags = append(req.Flags, "Detach")
|
||||||
|
}
|
||||||
|
if len(conf.ClientAuths) > 0 {
|
||||||
|
req.Flags = append(req.Flags, "BasicAuth")
|
||||||
|
}
|
||||||
|
if conf.NonAnonymous {
|
||||||
|
req.Flags = append(req.Flags, "NonAnonymous")
|
||||||
|
}
|
||||||
|
if conf.MaxStreamsCloseCircuit {
|
||||||
|
req.Flags = append(req.Flags, "MaxStreamsCloseCircuit")
|
||||||
|
}
|
||||||
|
// Set the key
|
||||||
|
switch key := conf.Key.(type) {
|
||||||
|
case nil:
|
||||||
|
svc.Version3 = conf.Version3
|
||||||
|
if conf.Version3 {
|
||||||
|
req.Key = control.GenKey(control.KeyAlgoED25519V3)
|
||||||
|
} else {
|
||||||
|
req.Key = control.GenKey(control.KeyAlgoRSA1024)
|
||||||
|
}
|
||||||
|
case control.GenKey:
|
||||||
|
svc.Version3 = conf.Version3
|
||||||
|
req.Key = key
|
||||||
|
case *rsa.PrivateKey:
|
||||||
|
svc.Key = key
|
||||||
|
svc.Version3 = false
|
||||||
|
if key.N == nil || key.N.BitLen() != 1024 {
|
||||||
|
err = fmt.Errorf("RSA key must be 1024 bits")
|
||||||
|
} else {
|
||||||
|
req.Key = &control.RSAKey{PrivateKey: key}
|
||||||
|
}
|
||||||
|
case *control.RSAKey:
|
||||||
|
svc.Key = key.PrivateKey
|
||||||
|
svc.Version3 = false
|
||||||
|
if key.N == nil || key.N.BitLen() != 1024 {
|
||||||
|
err = fmt.Errorf("RSA key must be 1024 bits")
|
||||||
|
} else {
|
||||||
|
req.Key = key
|
||||||
|
}
|
||||||
|
case ed25519.KeyPair:
|
||||||
|
svc.Key = key
|
||||||
|
svc.Version3 = true
|
||||||
|
req.Key = &control.ED25519Key{key}
|
||||||
|
case othered25519.PrivateKey:
|
||||||
|
properKey := ed25519.FromCryptoPrivateKey(key)
|
||||||
|
svc.Key = properKey
|
||||||
|
svc.Version3 = true
|
||||||
|
req.Key = &control.ED25519Key{properKey}
|
||||||
|
case *control.ED25519Key:
|
||||||
|
svc.Key = key.KeyPair
|
||||||
|
svc.Version3 = true
|
||||||
|
req.Key = key
|
||||||
|
default:
|
||||||
|
err = fmt.Errorf("Unrecognized key type: %T", key)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply the remote ports
|
||||||
|
if err == nil {
|
||||||
|
if len(conf.RemotePorts) == 0 {
|
||||||
|
tcpAddr, ok := svc.LocalListener.Addr().(*net.TCPAddr)
|
||||||
|
if !ok {
|
||||||
|
err = fmt.Errorf("Unable to derive local TCP port")
|
||||||
|
} else {
|
||||||
|
svc.RemotePorts = []int{tcpAddr.Port}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
svc.RemotePorts = make([]int, len(conf.RemotePorts))
|
||||||
|
copy(svc.RemotePorts, conf.RemotePorts)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Apply the local ports with the remote ports
|
||||||
|
if err == nil {
|
||||||
|
localAddr := svc.LocalListener.Addr().String()
|
||||||
|
if _, ok := svc.LocalListener.(*net.UnixListener); ok {
|
||||||
|
localAddr = "unix:" + localAddr
|
||||||
|
}
|
||||||
|
for _, remotePort := range svc.RemotePorts {
|
||||||
|
req.Ports = append(req.Ports, &control.KeyVal{Key: strconv.Itoa(remotePort), Val: localAddr})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the onion service
|
||||||
|
var resp *control.AddOnionResponse
|
||||||
|
if err == nil {
|
||||||
|
resp, err = t.Control.AddOnion(req)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply the response to the service
|
||||||
|
if err == nil {
|
||||||
|
svc.ID = resp.ServiceID
|
||||||
|
switch key := resp.Key.(type) {
|
||||||
|
case nil:
|
||||||
|
// Do nothing
|
||||||
|
case *control.RSAKey:
|
||||||
|
svc.Key = key.PrivateKey
|
||||||
|
case *control.ED25519Key:
|
||||||
|
svc.Key = key.KeyPair
|
||||||
|
default:
|
||||||
|
err = fmt.Errorf("Unrecognized result key type: %T", key)
|
||||||
|
}
|
||||||
|
// Client auths are the conf and then overridden by results
|
||||||
|
if len(conf.ClientAuths) > 0 {
|
||||||
|
svc.ClientAuths = make(map[string]string, len(conf.ClientAuths))
|
||||||
|
for k, v := range conf.ClientAuths {
|
||||||
|
svc.ClientAuths[k] = v
|
||||||
|
}
|
||||||
|
for k, v := range resp.ClientAuths {
|
||||||
|
svc.ClientAuths[k] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait if necessary
|
||||||
|
if err == nil && !conf.NoWait {
|
||||||
|
t.Debugf("Enabling network before waiting for publication")
|
||||||
|
// First make sure network is enabled
|
||||||
|
if err = t.EnableNetwork(ctx, true); err == nil {
|
||||||
|
t.Debugf("Waiting for publication")
|
||||||
|
// Now we'll take a similar approach to Stem. Several UPLOADs are sent out, so we count em. If we see
|
||||||
|
// UPLOADED, we succeeded. If we see failed, we count those. If there are as many failures as uploads, they
|
||||||
|
// all failed and it's a failure. NOTE: unlike Stem's comments that say they don't, we are actually seeing
|
||||||
|
// the service IDs for UPLOADED so we don't keep a map.
|
||||||
|
uploadsAttempted := 0
|
||||||
|
failures := []string{}
|
||||||
|
_, err = t.Control.EventWait(ctx, []control.EventCode{control.EventCodeHSDesc},
|
||||||
|
func(evt control.Event) (bool, error) {
|
||||||
|
hs, _ := evt.(*control.HSDescEvent)
|
||||||
|
if hs != nil && hs.Address == svc.ID {
|
||||||
|
switch hs.Action {
|
||||||
|
case "UPLOAD":
|
||||||
|
uploadsAttempted++
|
||||||
|
case "FAILED":
|
||||||
|
failures = append(failures,
|
||||||
|
fmt.Sprintf("Failed uploading to dir %v - reason: %v", hs.HSDir, hs.Reason))
|
||||||
|
if len(failures) == uploadsAttempted {
|
||||||
|
return false, fmt.Errorf("Failed all uploads, reasons: %v", failures)
|
||||||
|
}
|
||||||
|
case "UPLOADED":
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false, nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Give back err and close if there is an err
|
||||||
|
if err != nil {
|
||||||
|
if closeErr := svc.Close(); closeErr != nil {
|
||||||
|
err = fmt.Errorf("Error on listen: %v (also got error trying to close: %v)", err, closeErr)
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return svc, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Accept implements net.Listener.Accept.
|
||||||
|
func (o *OnionService) Accept() (net.Conn, error) {
|
||||||
|
return o.LocalListener.Accept()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Addr implements net.Listener.Addr just returning this object.
|
||||||
|
func (o *OnionService) Addr() net.Addr {
|
||||||
|
return o
|
||||||
|
}
|
||||||
|
|
||||||
|
// Network implements net.Addr.Network always returning "tcp".
|
||||||
|
func (o *OnionService) Network() string {
|
||||||
|
return "tcp"
|
||||||
|
}
|
||||||
|
|
||||||
|
// String implements net.Addr.String and returns "<serviceID>.onion:<virtport>".
|
||||||
|
func (o *OnionService) String() string {
|
||||||
|
return fmt.Sprintf("%v.onion:%v", o.ID, o.RemotePorts[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close implements net.Listener.Close and deletes the onion service and closes
|
||||||
|
// the LocalListener if CloseLocalListenerOnClose is true.
|
||||||
|
func (o *OnionService) Close() (err error) {
|
||||||
|
o.Tor.Debugf("Closing onion %v", o)
|
||||||
|
// Delete the onion first
|
||||||
|
if o.ID != "" {
|
||||||
|
err = o.Tor.Control.DelOnion(o.ID)
|
||||||
|
o.ID = ""
|
||||||
|
}
|
||||||
|
// Now if the local one needs to be closed, do it
|
||||||
|
if o.CloseLocalListenerOnClose && o.LocalListener != nil {
|
||||||
|
if closeErr := o.LocalListener.Close(); closeErr != nil {
|
||||||
|
if err != nil {
|
||||||
|
err = fmt.Errorf("Unable to close onion: %v (also unable to close local listener: %v)", err, closeErr)
|
||||||
|
} else {
|
||||||
|
err = closeErr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
o.LocalListener = nil
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
o.Tor.Debugf("Failed closing onion: %v", err)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
16
vendor/github.com/cretz/bine/tor/log.go
generated
vendored
Normal file
16
vendor/github.com/cretz/bine/tor/log.go
generated
vendored
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
package tor
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
// DebugEnabled returns true if there is a DebugWriter.
|
||||||
|
func (t *Tor) DebugEnabled() bool {
|
||||||
|
return t.DebugWriter != nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Debugf writes the formatted string with a newline appended to the DebugWriter
|
||||||
|
// if present.
|
||||||
|
func (t *Tor) Debugf(format string, args ...interface{}) {
|
||||||
|
if w := t.DebugWriter; w != nil {
|
||||||
|
fmt.Fprintf(w, format+"\n", args...)
|
||||||
|
}
|
||||||
|
}
|
453
vendor/github.com/cretz/bine/tor/tor.go
generated
vendored
Normal file
453
vendor/github.com/cretz/bine/tor/tor.go
generated
vendored
Normal file
@ -0,0 +1,453 @@
|
|||||||
|
package tor
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/textproto"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/cretz/bine/control"
|
||||||
|
|
||||||
|
"github.com/cretz/bine/process"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Tor is the wrapper around the Tor process and control port connection. It
|
||||||
|
// should be created with Start and developers should always call Close when
|
||||||
|
// done.
|
||||||
|
type Tor struct {
|
||||||
|
// Process is the Tor instance that is running.
|
||||||
|
Process process.Process
|
||||||
|
|
||||||
|
// Control is the Tor controller connection.
|
||||||
|
Control *control.Conn
|
||||||
|
|
||||||
|
// ProcessCancelFunc is the context cancellation func for the Tor process.
|
||||||
|
// It is used by Close and should not be called directly. This can be nil.
|
||||||
|
ProcessCancelFunc context.CancelFunc
|
||||||
|
|
||||||
|
// ControlPort is the port that Control is connected on. It is 0 if the
|
||||||
|
// connection is an embedded control connection.
|
||||||
|
ControlPort int
|
||||||
|
|
||||||
|
// DataDir is the path to the data directory that Tor is using.
|
||||||
|
DataDir string
|
||||||
|
|
||||||
|
// DeleteDataDirOnClose is true if, when Close is invoked, the entire
|
||||||
|
// directory will be deleted.
|
||||||
|
DeleteDataDirOnClose bool
|
||||||
|
|
||||||
|
// DebugWriter is the writer used for debug logs, or nil if debug logs
|
||||||
|
// should not be emitted.
|
||||||
|
DebugWriter io.Writer
|
||||||
|
|
||||||
|
// StopProcessOnClose, if true, will attempt to halt the process on close.
|
||||||
|
StopProcessOnClose bool
|
||||||
|
|
||||||
|
// GeoIPCreatedFile is the path, relative to DataDir, that was created from
|
||||||
|
// StartConf.GeoIPFileReader. It is empty if no file was created.
|
||||||
|
GeoIPCreatedFile string
|
||||||
|
|
||||||
|
// GeoIPv6CreatedFile is the path, relative to DataDir, that was created
|
||||||
|
// from StartConf.GeoIPFileReader. It is empty if no file was created.
|
||||||
|
GeoIPv6CreatedFile string
|
||||||
|
}
|
||||||
|
|
||||||
|
// StartConf is the configuration used for Start when starting a Tor instance. A
|
||||||
|
// default instance with no fields set is the default used for Start.
|
||||||
|
type StartConf struct {
|
||||||
|
// ExePath is the path to the Tor executable. If it is not present, "tor" is
|
||||||
|
// used either locally or on the PATH. This is ignored if ProcessCreator is
|
||||||
|
// set.
|
||||||
|
ExePath string
|
||||||
|
|
||||||
|
// ProcessCreator is the override to use a specific process creator. If set,
|
||||||
|
// ExePath is ignored.
|
||||||
|
ProcessCreator process.Creator
|
||||||
|
|
||||||
|
// UseEmbeddedControlConn can be set to true to use
|
||||||
|
// process.Process.EmbeddedControlConn() instead of creating a connection
|
||||||
|
// via ControlPort. Note, this only works when ProcessCreator is an
|
||||||
|
// embedded Tor creator with version >= 0.3.5.x.
|
||||||
|
UseEmbeddedControlConn bool
|
||||||
|
|
||||||
|
// ControlPort is the port to use for the Tor controller. If it is 0, Tor
|
||||||
|
// picks a port for use. This is ignored if UseEmbeddedControlConn is true.
|
||||||
|
ControlPort int
|
||||||
|
|
||||||
|
// DataDir is the directory used by Tor. If it is empty, a temporary
|
||||||
|
// directory is created in TempDataDirBase.
|
||||||
|
DataDir string
|
||||||
|
|
||||||
|
// TempDataDirBase is the parent directory that a temporary data directory
|
||||||
|
// will be created under for use by Tor. This is ignored if DataDir is not
|
||||||
|
// empty. If empty it is assumed to be the current working directory.
|
||||||
|
TempDataDirBase string
|
||||||
|
|
||||||
|
// RetainTempDataDir, if true, will not set the created temporary data
|
||||||
|
// directory to be deleted on close. This is ignored if DataDir is not
|
||||||
|
// empty.
|
||||||
|
RetainTempDataDir bool
|
||||||
|
|
||||||
|
// DisableCookieAuth, if true, will not use the default SAFECOOKIE
|
||||||
|
// authentication mechanism for the Tor controller.
|
||||||
|
DisableCookieAuth bool
|
||||||
|
|
||||||
|
// DisableEagerAuth, if true, will not authenticate on Start.
|
||||||
|
DisableEagerAuth bool
|
||||||
|
|
||||||
|
// EnableNetwork, if true, will connect to the wider Tor network on start.
|
||||||
|
EnableNetwork bool
|
||||||
|
|
||||||
|
// ExtraArgs is the set of extra args passed to the Tor instance when
|
||||||
|
// started.
|
||||||
|
ExtraArgs []string
|
||||||
|
|
||||||
|
// TorrcFile is the torrc file to set on start. If empty, a blank torrc is
|
||||||
|
// created in the data directory and is used instead.
|
||||||
|
TorrcFile string
|
||||||
|
|
||||||
|
// DebugWriter is the writer to use for debug logs, or nil for no debug
|
||||||
|
// logs.
|
||||||
|
DebugWriter io.Writer
|
||||||
|
|
||||||
|
// NoHush if true does not set --hush. By default --hush is set.
|
||||||
|
NoHush bool
|
||||||
|
|
||||||
|
// NoAutoSocksPort if true does not set "--SocksPort auto" as is done by
|
||||||
|
// default. This means the caller could set their own or just let it
|
||||||
|
// default to 9050.
|
||||||
|
NoAutoSocksPort bool
|
||||||
|
|
||||||
|
// GeoIPReader, if present, is called before start to copy geo IP files to
|
||||||
|
// the data directory. Errors are propagated. If the ReadCloser is present,
|
||||||
|
// it is copied to the data dir, overwriting as necessary, and then closed
|
||||||
|
// and the appropriate command line argument is added to reference it. If
|
||||||
|
// both the ReadCloser and error are nil, no copy or command line argument
|
||||||
|
// is used for that version. This is called twice, once with false and once
|
||||||
|
// with true for ipv6.
|
||||||
|
//
|
||||||
|
// This can be set to torutil/geoipembed.GeoIPReader to use an embedded
|
||||||
|
// source.
|
||||||
|
GeoIPFileReader func(ipv6 bool) (io.ReadCloser, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start a Tor instance and connect to it. If ctx is nil, context.Background()
|
||||||
|
// is used. If conf is nil, a default instance is used.
|
||||||
|
func Start(ctx context.Context, conf *StartConf) (*Tor, error) {
|
||||||
|
if ctx == nil {
|
||||||
|
ctx = context.Background()
|
||||||
|
}
|
||||||
|
if conf == nil {
|
||||||
|
conf = &StartConf{}
|
||||||
|
}
|
||||||
|
tor := &Tor{DataDir: conf.DataDir, DebugWriter: conf.DebugWriter, StopProcessOnClose: true}
|
||||||
|
// Create the data dir and make it absolute
|
||||||
|
if tor.DataDir == "" {
|
||||||
|
tempBase := conf.TempDataDirBase
|
||||||
|
if tempBase == "" {
|
||||||
|
tempBase = "."
|
||||||
|
}
|
||||||
|
var err error
|
||||||
|
if tempBase, err = filepath.Abs(tempBase); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if tor.DataDir, err = ioutil.TempDir(tempBase, "data-dir-"); err != nil {
|
||||||
|
return nil, fmt.Errorf("Unable to create temp data dir: %v", err)
|
||||||
|
}
|
||||||
|
tor.Debugf("Created temp data directory at: %v", tor.DataDir)
|
||||||
|
tor.DeleteDataDirOnClose = !conf.RetainTempDataDir
|
||||||
|
} else if err := os.MkdirAll(tor.DataDir, 0700); err != nil {
|
||||||
|
return nil, fmt.Errorf("Unable to create data dir: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// !!!! From this point on, we must close tor if we error !!!!
|
||||||
|
|
||||||
|
// Copy geoip stuff if necessary
|
||||||
|
err := tor.copyGeoIPFiles(conf)
|
||||||
|
// Start tor
|
||||||
|
if err == nil {
|
||||||
|
err = tor.startProcess(ctx, conf)
|
||||||
|
}
|
||||||
|
// Connect the controller
|
||||||
|
if err == nil {
|
||||||
|
err = tor.connectController(ctx, conf)
|
||||||
|
}
|
||||||
|
// Attempt eager auth w/ no password
|
||||||
|
if err == nil && !conf.DisableEagerAuth {
|
||||||
|
err = tor.Control.Authenticate("")
|
||||||
|
}
|
||||||
|
// If there was an error, we have to try to close here but it may leave the process open
|
||||||
|
if err != nil {
|
||||||
|
if closeErr := tor.Close(); closeErr != nil {
|
||||||
|
err = fmt.Errorf("Error on start: %v (also got error trying to close: %v)", err, closeErr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return tor, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Tor) copyGeoIPFiles(conf *StartConf) error {
|
||||||
|
if conf.GeoIPFileReader == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if r, err := conf.GeoIPFileReader(false); err != nil {
|
||||||
|
return fmt.Errorf("Unable to read geoip file: %v", err)
|
||||||
|
} else if r != nil {
|
||||||
|
t.GeoIPCreatedFile = "geoip"
|
||||||
|
if err := createFile(filepath.Join(t.DataDir, "geoip"), r); err != nil {
|
||||||
|
return fmt.Errorf("Unable to create geoip file: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if r, err := conf.GeoIPFileReader(true); err != nil {
|
||||||
|
return fmt.Errorf("Unable to read geoip6 file: %v", err)
|
||||||
|
} else if r != nil {
|
||||||
|
t.GeoIPv6CreatedFile = "geoip6"
|
||||||
|
if err := createFile(filepath.Join(t.DataDir, "geoip6"), r); err != nil {
|
||||||
|
return fmt.Errorf("Unable to create geoip6 file: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func createFile(to string, from io.ReadCloser) error {
|
||||||
|
f, err := os.Create(to)
|
||||||
|
if err == nil {
|
||||||
|
_, err = io.Copy(f, from)
|
||||||
|
if closeErr := f.Close(); err == nil {
|
||||||
|
err = closeErr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if closeErr := from.Close(); err == nil {
|
||||||
|
err = closeErr
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Tor) startProcess(ctx context.Context, conf *StartConf) error {
|
||||||
|
// Get the creator
|
||||||
|
creator := conf.ProcessCreator
|
||||||
|
if creator == nil {
|
||||||
|
torPath := conf.ExePath
|
||||||
|
if torPath == "" {
|
||||||
|
torPath = "tor"
|
||||||
|
}
|
||||||
|
creator = process.NewCreator(torPath)
|
||||||
|
}
|
||||||
|
// Build the args
|
||||||
|
args := []string{"--DataDirectory", t.DataDir}
|
||||||
|
if !conf.DisableCookieAuth {
|
||||||
|
args = append(args, "--CookieAuthentication", "1")
|
||||||
|
}
|
||||||
|
if !conf.EnableNetwork {
|
||||||
|
args = append(args, "--DisableNetwork", "1")
|
||||||
|
}
|
||||||
|
if !conf.NoHush {
|
||||||
|
args = append(args, "--hush")
|
||||||
|
}
|
||||||
|
if !conf.NoAutoSocksPort {
|
||||||
|
args = append(args, "--SocksPort", "auto")
|
||||||
|
}
|
||||||
|
if t.GeoIPCreatedFile != "" {
|
||||||
|
args = append(args, "--GeoIPFile", filepath.Join(t.DataDir, t.GeoIPCreatedFile))
|
||||||
|
}
|
||||||
|
if t.GeoIPv6CreatedFile != "" {
|
||||||
|
args = append(args, "--GeoIPv6File", filepath.Join(t.DataDir, t.GeoIPv6CreatedFile))
|
||||||
|
}
|
||||||
|
// If there is no Torrc file, create a blank temp one
|
||||||
|
torrcFileName := conf.TorrcFile
|
||||||
|
if torrcFileName == "" {
|
||||||
|
torrcFile, err := ioutil.TempFile(t.DataDir, "torrc-")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
torrcFileName = torrcFile.Name()
|
||||||
|
if err = torrcFile.Close(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
args = append(args, "-f", torrcFileName)
|
||||||
|
// Create file for Tor to write the control port to if it's not told to us and we're not embedded
|
||||||
|
var controlPortFileName string
|
||||||
|
var err error
|
||||||
|
if !conf.UseEmbeddedControlConn {
|
||||||
|
if conf.ControlPort == 0 {
|
||||||
|
controlPortFile, err := ioutil.TempFile(t.DataDir, "control-port-")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
controlPortFileName = controlPortFile.Name()
|
||||||
|
if err = controlPortFile.Close(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
args = append(args, "--ControlPort", "auto", "--ControlPortWriteToFile", controlPortFile.Name())
|
||||||
|
} else {
|
||||||
|
args = append(args, "--ControlPort", strconv.Itoa(conf.ControlPort))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Create process creator with args
|
||||||
|
var processCtx context.Context
|
||||||
|
processCtx, t.ProcessCancelFunc = context.WithCancel(ctx)
|
||||||
|
args = append(args, conf.ExtraArgs...)
|
||||||
|
p, err := creator.New(processCtx, args...)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// Use the embedded conn if requested
|
||||||
|
if conf.UseEmbeddedControlConn {
|
||||||
|
t.Debugf("Using embedded control connection")
|
||||||
|
conn, err := p.EmbeddedControlConn()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Unable to get embedded control conn: %v", err)
|
||||||
|
}
|
||||||
|
t.Control = control.NewConn(textproto.NewConn(conn))
|
||||||
|
t.Control.DebugWriter = t.DebugWriter
|
||||||
|
}
|
||||||
|
// Start process with the args
|
||||||
|
t.Debugf("Starting tor with args %v", args)
|
||||||
|
if err = p.Start(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
t.Process = p
|
||||||
|
// If not embedded, try a few times to read the control port file if we need to
|
||||||
|
if !conf.UseEmbeddedControlConn {
|
||||||
|
t.ControlPort = conf.ControlPort
|
||||||
|
if t.ControlPort == 0 {
|
||||||
|
ControlPortCheck:
|
||||||
|
for i := 0; i < 10; i++ {
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
err = ctx.Err()
|
||||||
|
break ControlPortCheck
|
||||||
|
default:
|
||||||
|
// Try to read the controlport file, or wait a bit
|
||||||
|
var byts []byte
|
||||||
|
if byts, err = ioutil.ReadFile(controlPortFileName); err != nil {
|
||||||
|
break ControlPortCheck
|
||||||
|
} else if t.ControlPort, err = process.ControlPortFromFileContents(string(byts)); err == nil {
|
||||||
|
break ControlPortCheck
|
||||||
|
}
|
||||||
|
time.Sleep(200 * time.Millisecond)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Unable to read control port file: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Tor) connectController(ctx context.Context, conf *StartConf) error {
|
||||||
|
// This doesn't apply if already connected (e.g. using embedded conn)
|
||||||
|
if t.Control != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
t.Debugf("Connecting to control port %v", t.ControlPort)
|
||||||
|
textConn, err := textproto.Dial("tcp", "127.0.0.1:"+strconv.Itoa(t.ControlPort))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
t.Control = control.NewConn(textConn)
|
||||||
|
t.Control.DebugWriter = t.DebugWriter
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// EnableNetwork sets DisableNetwork to 0 and optionally waits for bootstrap to
|
||||||
|
// complete. The context can be nil. If DisableNetwork isnt 1, this does
|
||||||
|
// nothing.
|
||||||
|
func (t *Tor) EnableNetwork(ctx context.Context, wait bool) error {
|
||||||
|
if ctx == nil {
|
||||||
|
ctx = context.Background()
|
||||||
|
}
|
||||||
|
// Only enable if DisableNetwork is 1
|
||||||
|
if vals, err := t.Control.GetConf("DisableNetwork"); err != nil {
|
||||||
|
return err
|
||||||
|
} else if len(vals) == 0 || vals[0].Key != "DisableNetwork" || vals[0].Val != "1" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
// Enable the network
|
||||||
|
if err := t.Control.SetConf(control.KeyVals("DisableNetwork", "0")...); err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
// If not waiting, leave
|
||||||
|
if !wait {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
// Wait for progress to hit 100
|
||||||
|
_, err := t.Control.EventWait(ctx, []control.EventCode{control.EventCodeStatusClient},
|
||||||
|
func(evt control.Event) (bool, error) {
|
||||||
|
if status, _ := evt.(*control.StatusEvent); status != nil && status.Action == "BOOTSTRAP" {
|
||||||
|
if status.Severity == "NOTICE" && status.Arguments["PROGRESS"] == "100" {
|
||||||
|
return true, nil
|
||||||
|
} else if status.Severity == "ERR" {
|
||||||
|
return false, fmt.Errorf("Failing bootstrapping, Tor warning: %v", status.Arguments["WARNING"])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false, nil
|
||||||
|
})
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close sends a halt to the Tor process if it can, closes the controller
|
||||||
|
// connection, and stops the process.
|
||||||
|
func (t *Tor) Close() error {
|
||||||
|
t.Debugf("Closing Tor")
|
||||||
|
errs := []error{}
|
||||||
|
// If controller is authenticated, send the quit signal to the process. Otherwise, just close the controller.
|
||||||
|
sentHalt := false
|
||||||
|
if t.Control != nil {
|
||||||
|
if t.Control.Authenticated && t.StopProcessOnClose {
|
||||||
|
if err := t.Control.Signal("HALT"); err != nil {
|
||||||
|
errs = append(errs, fmt.Errorf("Unable to signal halt: %v", err))
|
||||||
|
} else {
|
||||||
|
sentHalt = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Now close the controller
|
||||||
|
if err := t.Control.Close(); err != nil {
|
||||||
|
errs = append(errs, fmt.Errorf("Unable to close contrlller: %v", err))
|
||||||
|
} else {
|
||||||
|
t.Control = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if t.Process != nil {
|
||||||
|
// If we didn't halt, we have to force kill w/ the cancel func
|
||||||
|
if !sentHalt && t.StopProcessOnClose {
|
||||||
|
t.ProcessCancelFunc()
|
||||||
|
}
|
||||||
|
// Wait for a bit to make sure it stopped
|
||||||
|
errCh := make(chan error, 1)
|
||||||
|
var waitErr error
|
||||||
|
go func() { errCh <- t.Process.Wait() }()
|
||||||
|
select {
|
||||||
|
case waitErr = <-errCh:
|
||||||
|
if waitErr != nil {
|
||||||
|
errs = append(errs, fmt.Errorf("Process wait failed: %v", waitErr))
|
||||||
|
}
|
||||||
|
case <-time.After(300 * time.Millisecond):
|
||||||
|
errs = append(errs, fmt.Errorf("Process did not exit after 300 ms"))
|
||||||
|
}
|
||||||
|
if waitErr == nil {
|
||||||
|
t.Process = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Get rid of the entire data dir
|
||||||
|
if t.DeleteDataDirOnClose {
|
||||||
|
if err := os.RemoveAll(t.DataDir); err != nil {
|
||||||
|
errs = append(errs, fmt.Errorf("Failed to remove data dir %v: %v", t.DataDir, err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Combine the errors if present
|
||||||
|
if len(errs) == 0 {
|
||||||
|
return nil
|
||||||
|
} else if len(errs) == 1 {
|
||||||
|
t.Debugf("Error while closing Tor: %v", errs[0])
|
||||||
|
return errs[0]
|
||||||
|
}
|
||||||
|
t.Debugf("Errors while closing Tor: %v", errs)
|
||||||
|
return fmt.Errorf("Got %v errors while closing - %v", len(errs), errs)
|
||||||
|
}
|
2
vendor/github.com/cretz/bine/torutil/doc.go
generated
vendored
Normal file
2
vendor/github.com/cretz/bine/torutil/doc.go
generated
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
// Package torutil has generic utilities shared across the library.
|
||||||
|
package torutil
|
189
vendor/github.com/cretz/bine/torutil/ed25519/ed25519.go
generated
vendored
Normal file
189
vendor/github.com/cretz/bine/torutil/ed25519/ed25519.go
generated
vendored
Normal file
@ -0,0 +1,189 @@
|
|||||||
|
// Package ed25519 implements Tor/BitTorrent-like ed25519 keys.
|
||||||
|
//
|
||||||
|
// See the following stack overflow post for details on why
|
||||||
|
// golang.org/x/crypto/ed25519 can't be used:
|
||||||
|
// https://stackoverflow.com/questions/44810708/ed25519-public-result-is-different
|
||||||
|
package ed25519
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto"
|
||||||
|
"crypto/rand"
|
||||||
|
"crypto/sha512"
|
||||||
|
"errors"
|
||||||
|
"io"
|
||||||
|
|
||||||
|
"github.com/cretz/bine/torutil/ed25519/internal/edwards25519"
|
||||||
|
"golang.org/x/crypto/ed25519"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// PublicKeySize is the size, in bytes, of public keys as used in this package.
|
||||||
|
PublicKeySize = 32
|
||||||
|
// PrivateKeySize is the size, in bytes, of private keys as used in this package.
|
||||||
|
PrivateKeySize = 64
|
||||||
|
// SignatureSize is the size, in bytes, of signatures generated and verified by this package.
|
||||||
|
SignatureSize = 64
|
||||||
|
)
|
||||||
|
|
||||||
|
// PrivateKey is a 64-byte Ed25519 private key. Unlike
|
||||||
|
// golang.org/x/crypto/ed25519, this is just the digest and does not contain
|
||||||
|
// the public key within it. Instead call PublicKey() or better, call KeyPair()
|
||||||
|
// which stores the precomputed public key.
|
||||||
|
type PrivateKey []byte
|
||||||
|
|
||||||
|
// PublicKey is a 32-byte Ed25519 public key.
|
||||||
|
type PublicKey []byte
|
||||||
|
|
||||||
|
// FromCryptoPrivateKey converts a Go private key to the one in this package.
|
||||||
|
func FromCryptoPrivateKey(key ed25519.PrivateKey) KeyPair {
|
||||||
|
digest := sha512.Sum512(key[:32])
|
||||||
|
digest[0] &= 248
|
||||||
|
digest[31] &= 127
|
||||||
|
digest[31] |= 64
|
||||||
|
return &precomputedKeyPair{PrivateKeyBytes: digest[:], PublicKeyBytes: PublicKey(key[32:])}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FromCryptoPublicKey converts a Go public key to the one in this package.
|
||||||
|
func FromCryptoPublicKey(key ed25519.PublicKey) PublicKey {
|
||||||
|
return PublicKey(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
// KeyPair returns a new key pair with the public key precomputed.
|
||||||
|
func (p PrivateKey) KeyPair() KeyPair {
|
||||||
|
return &precomputedKeyPair{PrivateKeyBytes: p, PublicKeyBytes: p.PublicKey()}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrivateKey simply returns itself. Implements KeyPair.PrivateKey.
|
||||||
|
func (p PrivateKey) PrivateKey() PrivateKey { return p }
|
||||||
|
|
||||||
|
// Public simply delegates to PublicKey() to satisfy crypto.Signer. This method
|
||||||
|
// does a bit more work than the traditional Go ed25519's private key's Public()
|
||||||
|
// method so developers are encouraged to reuse the result or use KeyPair()
|
||||||
|
// which stores this value.
|
||||||
|
func (p PrivateKey) Public() crypto.PublicKey { return p.PublicKey() }
|
||||||
|
|
||||||
|
// PublicKey generates a public key for this private key. This method does a bit
|
||||||
|
// more work than the traditional Go ed25519's private key's Public() method so
|
||||||
|
// developers are encouraged to reuse the result or use KeyPair() which stores
|
||||||
|
// this value. Implements KeyPair.PublicKey.
|
||||||
|
func (p PrivateKey) PublicKey() PublicKey {
|
||||||
|
var A edwards25519.ExtendedGroupElement
|
||||||
|
var hBytes [32]byte
|
||||||
|
copy(hBytes[:], p[:])
|
||||||
|
edwards25519.GeScalarMultBase(&A, &hBytes)
|
||||||
|
var publicKeyBytes [32]byte
|
||||||
|
A.ToBytes(&publicKeyBytes)
|
||||||
|
return publicKeyBytes[:]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sign signs the given message with priv. Ed25519 performs two passes over
|
||||||
|
// messages to be signed and therefore cannot handle pre-hashed messages. Thus
|
||||||
|
// opts.HashFunc() must return zero to indicate the message hasn't been hashed.
|
||||||
|
// This can be achieved by passing crypto.Hash(0) as the value for opts.
|
||||||
|
func (p PrivateKey) Sign(rand io.Reader, message []byte, opts crypto.SignerOpts) ([]byte, error) {
|
||||||
|
if opts.HashFunc() != crypto.Hash(0) {
|
||||||
|
return nil, errors.New("ed25519: cannot sign hashed message")
|
||||||
|
}
|
||||||
|
return Sign(p, message), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify simply calls PublicKey().Verify(). Callers are encouraged to instead
|
||||||
|
// store a precomputed KeyPair (via KeyPair() or GenerateKey()) and call Verify
|
||||||
|
// on that.
|
||||||
|
func (p PrivateKey) Verify(message []byte, sig []byte) bool {
|
||||||
|
return p.PublicKey().Verify(message, sig)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify simply calls the package-level function Verify().
|
||||||
|
func (p PublicKey) Verify(message []byte, sig []byte) bool {
|
||||||
|
return Verify(p, message, sig)
|
||||||
|
}
|
||||||
|
|
||||||
|
// KeyPair is an interface for types with both keys. While PrivateKey does
|
||||||
|
// implement this, it generates the PublicKey on demand. For better performance,
|
||||||
|
// use the result of GenerateKey directly or call PrivateKey.KeyPair().
|
||||||
|
type KeyPair interface {
|
||||||
|
crypto.Signer
|
||||||
|
PrivateKey() PrivateKey
|
||||||
|
PublicKey() PublicKey
|
||||||
|
Verify(message []byte, sig []byte) bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type precomputedKeyPair struct {
|
||||||
|
PrivateKeyBytes PrivateKey
|
||||||
|
PublicKeyBytes PublicKey
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *precomputedKeyPair) PrivateKey() PrivateKey { return p.PrivateKeyBytes }
|
||||||
|
func (p *precomputedKeyPair) PublicKey() PublicKey { return p.PublicKeyBytes }
|
||||||
|
func (p *precomputedKeyPair) Public() crypto.PublicKey { return p.PublicKey() }
|
||||||
|
func (p *precomputedKeyPair) Sign(rand io.Reader, message []byte, opts crypto.SignerOpts) ([]byte, error) {
|
||||||
|
if opts.HashFunc() != crypto.Hash(0) {
|
||||||
|
return nil, errors.New("ed25519: cannot sign hashed message")
|
||||||
|
}
|
||||||
|
return Sign(p, message), nil
|
||||||
|
}
|
||||||
|
func (p *precomputedKeyPair) Verify(message []byte, sig []byte) bool {
|
||||||
|
return p.PublicKeyBytes.Verify(message, sig)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GenerateKey generates a public/private key pair using entropy from rand.
|
||||||
|
// If rand is nil, crypto/rand.Reader will be used.
|
||||||
|
func GenerateKey(rnd io.Reader) (KeyPair, error) {
|
||||||
|
if rnd == nil {
|
||||||
|
rnd = rand.Reader
|
||||||
|
}
|
||||||
|
rndByts := make([]byte, 32)
|
||||||
|
if _, err := io.ReadFull(rnd, rndByts); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
digest := sha512.Sum512(rndByts)
|
||||||
|
digest[0] &= 248
|
||||||
|
digest[31] &= 127
|
||||||
|
digest[31] |= 64
|
||||||
|
return PrivateKey(digest[:]).KeyPair(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sign signs the message with the given key pair.
|
||||||
|
func Sign(keyPair KeyPair, message []byte) []byte {
|
||||||
|
// Ref: https://stackoverflow.com/questions/44810708/ed25519-public-result-is-different
|
||||||
|
|
||||||
|
var privateKeyA [32]byte
|
||||||
|
copy(privateKeyA[:], keyPair.PrivateKey()) // we need this in an array later
|
||||||
|
var messageDigest, hramDigest [64]byte
|
||||||
|
|
||||||
|
h := sha512.New()
|
||||||
|
h.Write(keyPair.PrivateKey()[32:])
|
||||||
|
h.Write(message)
|
||||||
|
h.Sum(messageDigest[:0])
|
||||||
|
|
||||||
|
var messageDigestReduced [32]byte
|
||||||
|
edwards25519.ScReduce(&messageDigestReduced, &messageDigest)
|
||||||
|
var R edwards25519.ExtendedGroupElement
|
||||||
|
edwards25519.GeScalarMultBase(&R, &messageDigestReduced)
|
||||||
|
|
||||||
|
var encodedR [32]byte
|
||||||
|
R.ToBytes(&encodedR)
|
||||||
|
|
||||||
|
h.Reset()
|
||||||
|
h.Write(encodedR[:])
|
||||||
|
h.Write(keyPair.PublicKey())
|
||||||
|
h.Write(message)
|
||||||
|
h.Sum(hramDigest[:0])
|
||||||
|
var hramDigestReduced [32]byte
|
||||||
|
edwards25519.ScReduce(&hramDigestReduced, &hramDigest)
|
||||||
|
|
||||||
|
var s [32]byte
|
||||||
|
edwards25519.ScMulAdd(&s, &hramDigestReduced, &privateKeyA, &messageDigestReduced)
|
||||||
|
|
||||||
|
signature := make([]byte, 64)
|
||||||
|
copy(signature[:], encodedR[:])
|
||||||
|
copy(signature[32:], s[:])
|
||||||
|
|
||||||
|
return signature
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify verifies a signed message.
|
||||||
|
func Verify(p PublicKey, message []byte, sig []byte) bool {
|
||||||
|
return ed25519.Verify(ed25519.PublicKey(p), message, sig)
|
||||||
|
}
|
1
vendor/github.com/cretz/bine/torutil/ed25519/internal/edwards25519/README.md
generated
vendored
Normal file
1
vendor/github.com/cretz/bine/torutil/ed25519/internal/edwards25519/README.md
generated
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
This is taken from https://github.com/golang/crypto/tree/1a580b3eff7814fc9b40602fd35256c63b50f491/ed25519/internal/edwards25519
|
1422
vendor/github.com/cretz/bine/torutil/ed25519/internal/edwards25519/const.go
generated
vendored
Normal file
1422
vendor/github.com/cretz/bine/torutil/ed25519/internal/edwards25519/const.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1793
vendor/github.com/cretz/bine/torutil/ed25519/internal/edwards25519/edwards25519.go
generated
vendored
Normal file
1793
vendor/github.com/cretz/bine/torutil/ed25519/internal/edwards25519/edwards25519.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
85
vendor/github.com/cretz/bine/torutil/key.go
generated
vendored
Normal file
85
vendor/github.com/cretz/bine/torutil/key.go
generated
vendored
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
package torutil
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto"
|
||||||
|
"crypto/rsa"
|
||||||
|
"crypto/sha1"
|
||||||
|
"crypto/x509"
|
||||||
|
"encoding/base32"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/cretz/bine/torutil/ed25519"
|
||||||
|
"golang.org/x/crypto/sha3"
|
||||||
|
)
|
||||||
|
|
||||||
|
var serviceIDEncoding = base32.StdEncoding.WithPadding(base32.NoPadding)
|
||||||
|
|
||||||
|
// OnionServiceIDFromPrivateKey generates the onion service ID from the given
|
||||||
|
// private key. This panics if the private key is not a 1024-bit
|
||||||
|
// crypto/*rsa.PrivateKey or github.com/cretz/bine/torutil/ed25519.KeyPair.
|
||||||
|
func OnionServiceIDFromPrivateKey(key crypto.PrivateKey) string {
|
||||||
|
switch k := key.(type) {
|
||||||
|
case *rsa.PrivateKey:
|
||||||
|
return OnionServiceIDFromV2PublicKey(&k.PublicKey)
|
||||||
|
case ed25519.KeyPair:
|
||||||
|
return OnionServiceIDFromV3PublicKey(k.PublicKey())
|
||||||
|
}
|
||||||
|
panic(fmt.Sprintf("Unrecognized private key type: %T", key))
|
||||||
|
}
|
||||||
|
|
||||||
|
// OnionServiceIDFromPublicKey generates the onion service ID from the given
|
||||||
|
// public key. This panics if the public key is not a 1024-bit
|
||||||
|
// crypto/*rsa.PublicKey or github.com/cretz/bine/torutil/ed25519.PublicKey.
|
||||||
|
func OnionServiceIDFromPublicKey(key crypto.PublicKey) string {
|
||||||
|
switch k := key.(type) {
|
||||||
|
case *rsa.PublicKey:
|
||||||
|
return OnionServiceIDFromV2PublicKey(k)
|
||||||
|
case ed25519.PublicKey:
|
||||||
|
return OnionServiceIDFromV3PublicKey(k)
|
||||||
|
}
|
||||||
|
panic(fmt.Sprintf("Unrecognized public key type: %T", key))
|
||||||
|
}
|
||||||
|
|
||||||
|
// OnionServiceIDFromV2PublicKey generates a V2 service ID for the given
|
||||||
|
// RSA-1024 public key. Panics if not a 1024-bit key.
|
||||||
|
func OnionServiceIDFromV2PublicKey(key *rsa.PublicKey) string {
|
||||||
|
if key.N.BitLen() != 1024 {
|
||||||
|
panic("RSA key not 1024 bit")
|
||||||
|
}
|
||||||
|
h := sha1.New()
|
||||||
|
h.Write(x509.MarshalPKCS1PublicKey(key))
|
||||||
|
return strings.ToLower(serviceIDEncoding.EncodeToString(h.Sum(nil)[:10]))
|
||||||
|
}
|
||||||
|
|
||||||
|
// OnionServiceIDFromV3PublicKey generates a V3 service ID for the given
|
||||||
|
// ED25519 public key.
|
||||||
|
func OnionServiceIDFromV3PublicKey(key ed25519.PublicKey) string {
|
||||||
|
checkSum := sha3.Sum256(append(append([]byte(".onion checksum"), key...), 0x03))
|
||||||
|
var keyBytes [35]byte
|
||||||
|
copy(keyBytes[:], key)
|
||||||
|
keyBytes[32] = checkSum[0]
|
||||||
|
keyBytes[33] = checkSum[1]
|
||||||
|
keyBytes[34] = 0x03
|
||||||
|
return strings.ToLower(serviceIDEncoding.EncodeToString(keyBytes[:]))
|
||||||
|
}
|
||||||
|
|
||||||
|
// PublicKeyFromV3OnionServiceID returns a public key for the given service ID
|
||||||
|
// or an error if the service ID is invalid.
|
||||||
|
func PublicKeyFromV3OnionServiceID(id string) (ed25519.PublicKey, error) {
|
||||||
|
byts, err := serviceIDEncoding.DecodeString(strings.ToUpper(id))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
} else if len(byts) != 35 {
|
||||||
|
return nil, fmt.Errorf("Invalid id length")
|
||||||
|
} else if byts[34] != 0x03 {
|
||||||
|
return nil, fmt.Errorf("Invalid version")
|
||||||
|
}
|
||||||
|
// Do a checksum check
|
||||||
|
key := ed25519.PublicKey(byts[:32])
|
||||||
|
checkSum := sha3.Sum256(append(append([]byte(".onion checksum"), key...), 0x03))
|
||||||
|
if byts[32] != checkSum[0] || byts[33] != checkSum[1] {
|
||||||
|
return nil, fmt.Errorf("Invalid checksum")
|
||||||
|
}
|
||||||
|
return key, nil
|
||||||
|
}
|
112
vendor/github.com/cretz/bine/torutil/string.go
generated
vendored
Normal file
112
vendor/github.com/cretz/bine/torutil/string.go
generated
vendored
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
package torutil
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// PartitionString returns the two parts of a string delimited by the first
|
||||||
|
// occurrence of ch. If ch does not exist, the second string is empty and the
|
||||||
|
// resulting bool is false. Otherwise it is true.
|
||||||
|
func PartitionString(str string, ch byte) (string, string, bool) {
|
||||||
|
index := strings.IndexByte(str, ch)
|
||||||
|
if index == -1 {
|
||||||
|
return str, "", false
|
||||||
|
}
|
||||||
|
return str[:index], str[index+1:], true
|
||||||
|
}
|
||||||
|
|
||||||
|
// PartitionStringFromEnd is same as PartitionString except it delimts by the
|
||||||
|
// last occurrence of ch instead of the first.
|
||||||
|
func PartitionStringFromEnd(str string, ch byte) (string, string, bool) {
|
||||||
|
index := strings.LastIndexByte(str, ch)
|
||||||
|
if index == -1 {
|
||||||
|
return str, "", false
|
||||||
|
}
|
||||||
|
return str[:index], str[index+1:], true
|
||||||
|
}
|
||||||
|
|
||||||
|
// EscapeSimpleQuotedStringIfNeeded calls EscapeSimpleQuotedString only if the
|
||||||
|
// string contains a space, backslash, double quote, newline, or carriage return
|
||||||
|
// character.
|
||||||
|
func EscapeSimpleQuotedStringIfNeeded(str string) string {
|
||||||
|
if strings.ContainsAny(str, " \\\"\r\n") {
|
||||||
|
return EscapeSimpleQuotedString(str)
|
||||||
|
}
|
||||||
|
return str
|
||||||
|
}
|
||||||
|
|
||||||
|
var simpleQuotedStringEscapeReplacer = strings.NewReplacer(
|
||||||
|
"\\", "\\\\",
|
||||||
|
"\"", "\\\"",
|
||||||
|
"\r", "\\r",
|
||||||
|
"\n", "\\n",
|
||||||
|
)
|
||||||
|
|
||||||
|
// EscapeSimpleQuotedString calls EscapeSimpleQuotedStringContents and then
|
||||||
|
// surrounds the entire string with double quotes.
|
||||||
|
func EscapeSimpleQuotedString(str string) string {
|
||||||
|
return "\"" + EscapeSimpleQuotedStringContents(str) + "\""
|
||||||
|
}
|
||||||
|
|
||||||
|
// EscapeSimpleQuotedStringContents escapes backslashes, double quotes,
|
||||||
|
// newlines, and carriage returns in str.
|
||||||
|
func EscapeSimpleQuotedStringContents(str string) string {
|
||||||
|
return simpleQuotedStringEscapeReplacer.Replace(str)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnescapeSimpleQuotedStringIfNeeded calls UnescapeSimpleQuotedString only if
|
||||||
|
// str is surrounded with double quotes.
|
||||||
|
func UnescapeSimpleQuotedStringIfNeeded(str string) (string, error) {
|
||||||
|
if len(str) >= 2 && str[0] == '"' && str[len(str)-1] == '"' {
|
||||||
|
return UnescapeSimpleQuotedString(str)
|
||||||
|
}
|
||||||
|
return str, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnescapeSimpleQuotedString removes surrounding double quotes and calls
|
||||||
|
// UnescapeSimpleQuotedStringContents.
|
||||||
|
func UnescapeSimpleQuotedString(str string) (string, error) {
|
||||||
|
if len(str) < 2 || str[0] != '"' || str[len(str)-1] != '"' {
|
||||||
|
return "", fmt.Errorf("Missing quotes")
|
||||||
|
}
|
||||||
|
return UnescapeSimpleQuotedStringContents(str[1 : len(str)-1])
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnescapeSimpleQuotedStringContents unescapes backslashes, double quotes,
|
||||||
|
// newlines, and carriage returns. Also errors if those aren't escaped.
|
||||||
|
func UnescapeSimpleQuotedStringContents(str string) (string, error) {
|
||||||
|
ret := ""
|
||||||
|
escaping := false
|
||||||
|
for _, c := range str {
|
||||||
|
switch c {
|
||||||
|
case '\\':
|
||||||
|
if escaping {
|
||||||
|
ret += "\\"
|
||||||
|
}
|
||||||
|
escaping = !escaping
|
||||||
|
case '"':
|
||||||
|
if !escaping {
|
||||||
|
return "", fmt.Errorf("Unescaped quote")
|
||||||
|
}
|
||||||
|
ret += "\""
|
||||||
|
escaping = false
|
||||||
|
case '\r', '\n':
|
||||||
|
return "", fmt.Errorf("Unescaped newline or carriage return")
|
||||||
|
default:
|
||||||
|
if escaping {
|
||||||
|
if c == 'r' {
|
||||||
|
ret += "\r"
|
||||||
|
} else if c == 'n' {
|
||||||
|
ret += "\n"
|
||||||
|
} else {
|
||||||
|
return "", fmt.Errorf("Unexpected escape")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ret += string(c)
|
||||||
|
}
|
||||||
|
escaping = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret, nil
|
||||||
|
}
|
3
vendor/golang.org/x/crypto/AUTHORS
generated
vendored
Normal file
3
vendor/golang.org/x/crypto/AUTHORS
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# This source code refers to The Go Authors for copyright purposes.
|
||||||
|
# The master list of authors is in the main Go distribution,
|
||||||
|
# visible at https://tip.golang.org/AUTHORS.
|
3
vendor/golang.org/x/crypto/CONTRIBUTORS
generated
vendored
Normal file
3
vendor/golang.org/x/crypto/CONTRIBUTORS
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# This source code was written by the Go contributors.
|
||||||
|
# The master list of contributors is in the main Go distribution,
|
||||||
|
# visible at https://tip.golang.org/CONTRIBUTORS.
|
27
vendor/golang.org/x/crypto/LICENSE
generated
vendored
Normal file
27
vendor/golang.org/x/crypto/LICENSE
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
Copyright (c) 2009 The Go Authors. All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* 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.
|
||||||
|
* Neither the name of Google Inc. nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
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
|
||||||
|
OWNER 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.
|
22
vendor/golang.org/x/crypto/PATENTS
generated
vendored
Normal file
22
vendor/golang.org/x/crypto/PATENTS
generated
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
Additional IP Rights Grant (Patents)
|
||||||
|
|
||||||
|
"This implementation" means the copyrightable works distributed by
|
||||||
|
Google as part of the Go project.
|
||||||
|
|
||||||
|
Google hereby grants to You a perpetual, worldwide, non-exclusive,
|
||||||
|
no-charge, royalty-free, irrevocable (except as stated in this section)
|
||||||
|
patent license to make, have made, use, offer to sell, sell, import,
|
||||||
|
transfer and otherwise run, modify and propagate the contents of this
|
||||||
|
implementation of Go, where such license applies only to those patent
|
||||||
|
claims, both currently owned or controlled by Google and acquired in
|
||||||
|
the future, licensable by Google that are necessarily infringed by this
|
||||||
|
implementation of Go. This grant does not include claims that would be
|
||||||
|
infringed only as a consequence of further modification of this
|
||||||
|
implementation. If you or your agent or exclusive licensee institute or
|
||||||
|
order or agree to the institution of patent litigation against any
|
||||||
|
entity (including a cross-claim or counterclaim in a lawsuit) alleging
|
||||||
|
that this implementation of Go or any code incorporated within this
|
||||||
|
implementation of Go constitutes direct or contributory patent
|
||||||
|
infringement, or inducement of patent infringement, then any patent
|
||||||
|
rights granted to you under this License for this implementation of Go
|
||||||
|
shall terminate as of the date such litigation is filed.
|
222
vendor/golang.org/x/crypto/ed25519/ed25519.go
generated
vendored
Normal file
222
vendor/golang.org/x/crypto/ed25519/ed25519.go
generated
vendored
Normal file
@ -0,0 +1,222 @@
|
|||||||
|
// Copyright 2016 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// In Go 1.13, the ed25519 package was promoted to the standard library as
|
||||||
|
// crypto/ed25519, and this package became a wrapper for the standard library one.
|
||||||
|
//
|
||||||
|
// +build !go1.13
|
||||||
|
|
||||||
|
// Package ed25519 implements the Ed25519 signature algorithm. See
|
||||||
|
// https://ed25519.cr.yp.to/.
|
||||||
|
//
|
||||||
|
// These functions are also compatible with the “Ed25519” function defined in
|
||||||
|
// RFC 8032. However, unlike RFC 8032's formulation, this package's private key
|
||||||
|
// representation includes a public key suffix to make multiple signing
|
||||||
|
// operations with the same key more efficient. This package refers to the RFC
|
||||||
|
// 8032 private key as the “seed”.
|
||||||
|
package ed25519
|
||||||
|
|
||||||
|
// This code is a port of the public domain, “ref10” implementation of ed25519
|
||||||
|
// from SUPERCOP.
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"crypto"
|
||||||
|
cryptorand "crypto/rand"
|
||||||
|
"crypto/sha512"
|
||||||
|
"errors"
|
||||||
|
"io"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"golang.org/x/crypto/ed25519/internal/edwards25519"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// PublicKeySize is the size, in bytes, of public keys as used in this package.
|
||||||
|
PublicKeySize = 32
|
||||||
|
// PrivateKeySize is the size, in bytes, of private keys as used in this package.
|
||||||
|
PrivateKeySize = 64
|
||||||
|
// SignatureSize is the size, in bytes, of signatures generated and verified by this package.
|
||||||
|
SignatureSize = 64
|
||||||
|
// SeedSize is the size, in bytes, of private key seeds. These are the private key representations used by RFC 8032.
|
||||||
|
SeedSize = 32
|
||||||
|
)
|
||||||
|
|
||||||
|
// PublicKey is the type of Ed25519 public keys.
|
||||||
|
type PublicKey []byte
|
||||||
|
|
||||||
|
// PrivateKey is the type of Ed25519 private keys. It implements crypto.Signer.
|
||||||
|
type PrivateKey []byte
|
||||||
|
|
||||||
|
// Public returns the PublicKey corresponding to priv.
|
||||||
|
func (priv PrivateKey) Public() crypto.PublicKey {
|
||||||
|
publicKey := make([]byte, PublicKeySize)
|
||||||
|
copy(publicKey, priv[32:])
|
||||||
|
return PublicKey(publicKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Seed returns the private key seed corresponding to priv. It is provided for
|
||||||
|
// interoperability with RFC 8032. RFC 8032's private keys correspond to seeds
|
||||||
|
// in this package.
|
||||||
|
func (priv PrivateKey) Seed() []byte {
|
||||||
|
seed := make([]byte, SeedSize)
|
||||||
|
copy(seed, priv[:32])
|
||||||
|
return seed
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sign signs the given message with priv.
|
||||||
|
// Ed25519 performs two passes over messages to be signed and therefore cannot
|
||||||
|
// handle pre-hashed messages. Thus opts.HashFunc() must return zero to
|
||||||
|
// indicate the message hasn't been hashed. This can be achieved by passing
|
||||||
|
// crypto.Hash(0) as the value for opts.
|
||||||
|
func (priv PrivateKey) Sign(rand io.Reader, message []byte, opts crypto.SignerOpts) (signature []byte, err error) {
|
||||||
|
if opts.HashFunc() != crypto.Hash(0) {
|
||||||
|
return nil, errors.New("ed25519: cannot sign hashed message")
|
||||||
|
}
|
||||||
|
|
||||||
|
return Sign(priv, message), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GenerateKey generates a public/private key pair using entropy from rand.
|
||||||
|
// If rand is nil, crypto/rand.Reader will be used.
|
||||||
|
func GenerateKey(rand io.Reader) (PublicKey, PrivateKey, error) {
|
||||||
|
if rand == nil {
|
||||||
|
rand = cryptorand.Reader
|
||||||
|
}
|
||||||
|
|
||||||
|
seed := make([]byte, SeedSize)
|
||||||
|
if _, err := io.ReadFull(rand, seed); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
privateKey := NewKeyFromSeed(seed)
|
||||||
|
publicKey := make([]byte, PublicKeySize)
|
||||||
|
copy(publicKey, privateKey[32:])
|
||||||
|
|
||||||
|
return publicKey, privateKey, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewKeyFromSeed calculates a private key from a seed. It will panic if
|
||||||
|
// len(seed) is not SeedSize. This function is provided for interoperability
|
||||||
|
// with RFC 8032. RFC 8032's private keys correspond to seeds in this
|
||||||
|
// package.
|
||||||
|
func NewKeyFromSeed(seed []byte) PrivateKey {
|
||||||
|
if l := len(seed); l != SeedSize {
|
||||||
|
panic("ed25519: bad seed length: " + strconv.Itoa(l))
|
||||||
|
}
|
||||||
|
|
||||||
|
digest := sha512.Sum512(seed)
|
||||||
|
digest[0] &= 248
|
||||||
|
digest[31] &= 127
|
||||||
|
digest[31] |= 64
|
||||||
|
|
||||||
|
var A edwards25519.ExtendedGroupElement
|
||||||
|
var hBytes [32]byte
|
||||||
|
copy(hBytes[:], digest[:])
|
||||||
|
edwards25519.GeScalarMultBase(&A, &hBytes)
|
||||||
|
var publicKeyBytes [32]byte
|
||||||
|
A.ToBytes(&publicKeyBytes)
|
||||||
|
|
||||||
|
privateKey := make([]byte, PrivateKeySize)
|
||||||
|
copy(privateKey, seed)
|
||||||
|
copy(privateKey[32:], publicKeyBytes[:])
|
||||||
|
|
||||||
|
return privateKey
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sign signs the message with privateKey and returns a signature. It will
|
||||||
|
// panic if len(privateKey) is not PrivateKeySize.
|
||||||
|
func Sign(privateKey PrivateKey, message []byte) []byte {
|
||||||
|
if l := len(privateKey); l != PrivateKeySize {
|
||||||
|
panic("ed25519: bad private key length: " + strconv.Itoa(l))
|
||||||
|
}
|
||||||
|
|
||||||
|
h := sha512.New()
|
||||||
|
h.Write(privateKey[:32])
|
||||||
|
|
||||||
|
var digest1, messageDigest, hramDigest [64]byte
|
||||||
|
var expandedSecretKey [32]byte
|
||||||
|
h.Sum(digest1[:0])
|
||||||
|
copy(expandedSecretKey[:], digest1[:])
|
||||||
|
expandedSecretKey[0] &= 248
|
||||||
|
expandedSecretKey[31] &= 63
|
||||||
|
expandedSecretKey[31] |= 64
|
||||||
|
|
||||||
|
h.Reset()
|
||||||
|
h.Write(digest1[32:])
|
||||||
|
h.Write(message)
|
||||||
|
h.Sum(messageDigest[:0])
|
||||||
|
|
||||||
|
var messageDigestReduced [32]byte
|
||||||
|
edwards25519.ScReduce(&messageDigestReduced, &messageDigest)
|
||||||
|
var R edwards25519.ExtendedGroupElement
|
||||||
|
edwards25519.GeScalarMultBase(&R, &messageDigestReduced)
|
||||||
|
|
||||||
|
var encodedR [32]byte
|
||||||
|
R.ToBytes(&encodedR)
|
||||||
|
|
||||||
|
h.Reset()
|
||||||
|
h.Write(encodedR[:])
|
||||||
|
h.Write(privateKey[32:])
|
||||||
|
h.Write(message)
|
||||||
|
h.Sum(hramDigest[:0])
|
||||||
|
var hramDigestReduced [32]byte
|
||||||
|
edwards25519.ScReduce(&hramDigestReduced, &hramDigest)
|
||||||
|
|
||||||
|
var s [32]byte
|
||||||
|
edwards25519.ScMulAdd(&s, &hramDigestReduced, &expandedSecretKey, &messageDigestReduced)
|
||||||
|
|
||||||
|
signature := make([]byte, SignatureSize)
|
||||||
|
copy(signature[:], encodedR[:])
|
||||||
|
copy(signature[32:], s[:])
|
||||||
|
|
||||||
|
return signature
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify reports whether sig is a valid signature of message by publicKey. It
|
||||||
|
// will panic if len(publicKey) is not PublicKeySize.
|
||||||
|
func Verify(publicKey PublicKey, message, sig []byte) bool {
|
||||||
|
if l := len(publicKey); l != PublicKeySize {
|
||||||
|
panic("ed25519: bad public key length: " + strconv.Itoa(l))
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(sig) != SignatureSize || sig[63]&224 != 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
var A edwards25519.ExtendedGroupElement
|
||||||
|
var publicKeyBytes [32]byte
|
||||||
|
copy(publicKeyBytes[:], publicKey)
|
||||||
|
if !A.FromBytes(&publicKeyBytes) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
edwards25519.FeNeg(&A.X, &A.X)
|
||||||
|
edwards25519.FeNeg(&A.T, &A.T)
|
||||||
|
|
||||||
|
h := sha512.New()
|
||||||
|
h.Write(sig[:32])
|
||||||
|
h.Write(publicKey[:])
|
||||||
|
h.Write(message)
|
||||||
|
var digest [64]byte
|
||||||
|
h.Sum(digest[:0])
|
||||||
|
|
||||||
|
var hReduced [32]byte
|
||||||
|
edwards25519.ScReduce(&hReduced, &digest)
|
||||||
|
|
||||||
|
var R edwards25519.ProjectiveGroupElement
|
||||||
|
var s [32]byte
|
||||||
|
copy(s[:], sig[32:])
|
||||||
|
|
||||||
|
// https://tools.ietf.org/html/rfc8032#section-5.1.7 requires that s be in
|
||||||
|
// the range [0, order) in order to prevent signature malleability.
|
||||||
|
if !edwards25519.ScMinimal(&s) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
edwards25519.GeDoubleScalarMultVartime(&R, &hReduced, &A, &s)
|
||||||
|
|
||||||
|
var checkR [32]byte
|
||||||
|
R.ToBytes(&checkR)
|
||||||
|
return bytes.Equal(sig[:32], checkR[:])
|
||||||
|
}
|
73
vendor/golang.org/x/crypto/ed25519/ed25519_go113.go
generated
vendored
Normal file
73
vendor/golang.org/x/crypto/ed25519/ed25519_go113.go
generated
vendored
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
// Copyright 2019 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build go1.13
|
||||||
|
|
||||||
|
// Package ed25519 implements the Ed25519 signature algorithm. See
|
||||||
|
// https://ed25519.cr.yp.to/.
|
||||||
|
//
|
||||||
|
// These functions are also compatible with the “Ed25519” function defined in
|
||||||
|
// RFC 8032. However, unlike RFC 8032's formulation, this package's private key
|
||||||
|
// representation includes a public key suffix to make multiple signing
|
||||||
|
// operations with the same key more efficient. This package refers to the RFC
|
||||||
|
// 8032 private key as the “seed”.
|
||||||
|
//
|
||||||
|
// Beginning with Go 1.13, the functionality of this package was moved to the
|
||||||
|
// standard library as crypto/ed25519. This package only acts as a compatibility
|
||||||
|
// wrapper.
|
||||||
|
package ed25519
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/ed25519"
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// PublicKeySize is the size, in bytes, of public keys as used in this package.
|
||||||
|
PublicKeySize = 32
|
||||||
|
// PrivateKeySize is the size, in bytes, of private keys as used in this package.
|
||||||
|
PrivateKeySize = 64
|
||||||
|
// SignatureSize is the size, in bytes, of signatures generated and verified by this package.
|
||||||
|
SignatureSize = 64
|
||||||
|
// SeedSize is the size, in bytes, of private key seeds. These are the private key representations used by RFC 8032.
|
||||||
|
SeedSize = 32
|
||||||
|
)
|
||||||
|
|
||||||
|
// PublicKey is the type of Ed25519 public keys.
|
||||||
|
//
|
||||||
|
// This type is an alias for crypto/ed25519's PublicKey type.
|
||||||
|
// See the crypto/ed25519 package for the methods on this type.
|
||||||
|
type PublicKey = ed25519.PublicKey
|
||||||
|
|
||||||
|
// PrivateKey is the type of Ed25519 private keys. It implements crypto.Signer.
|
||||||
|
//
|
||||||
|
// This type is an alias for crypto/ed25519's PrivateKey type.
|
||||||
|
// See the crypto/ed25519 package for the methods on this type.
|
||||||
|
type PrivateKey = ed25519.PrivateKey
|
||||||
|
|
||||||
|
// GenerateKey generates a public/private key pair using entropy from rand.
|
||||||
|
// If rand is nil, crypto/rand.Reader will be used.
|
||||||
|
func GenerateKey(rand io.Reader) (PublicKey, PrivateKey, error) {
|
||||||
|
return ed25519.GenerateKey(rand)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewKeyFromSeed calculates a private key from a seed. It will panic if
|
||||||
|
// len(seed) is not SeedSize. This function is provided for interoperability
|
||||||
|
// with RFC 8032. RFC 8032's private keys correspond to seeds in this
|
||||||
|
// package.
|
||||||
|
func NewKeyFromSeed(seed []byte) PrivateKey {
|
||||||
|
return ed25519.NewKeyFromSeed(seed)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sign signs the message with privateKey and returns a signature. It will
|
||||||
|
// panic if len(privateKey) is not PrivateKeySize.
|
||||||
|
func Sign(privateKey PrivateKey, message []byte) []byte {
|
||||||
|
return ed25519.Sign(privateKey, message)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify reports whether sig is a valid signature of message by publicKey. It
|
||||||
|
// will panic if len(publicKey) is not PublicKeySize.
|
||||||
|
func Verify(publicKey PublicKey, message, sig []byte) bool {
|
||||||
|
return ed25519.Verify(publicKey, message, sig)
|
||||||
|
}
|
1422
vendor/golang.org/x/crypto/ed25519/internal/edwards25519/const.go
generated
vendored
Normal file
1422
vendor/golang.org/x/crypto/ed25519/internal/edwards25519/const.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1793
vendor/golang.org/x/crypto/ed25519/internal/edwards25519/edwards25519.go
generated
vendored
Normal file
1793
vendor/golang.org/x/crypto/ed25519/internal/edwards25519/edwards25519.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
66
vendor/golang.org/x/crypto/sha3/doc.go
generated
vendored
Normal file
66
vendor/golang.org/x/crypto/sha3/doc.go
generated
vendored
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Package sha3 implements the SHA-3 fixed-output-length hash functions and
|
||||||
|
// the SHAKE variable-output-length hash functions defined by FIPS-202.
|
||||||
|
//
|
||||||
|
// Both types of hash function use the "sponge" construction and the Keccak
|
||||||
|
// permutation. For a detailed specification see http://keccak.noekeon.org/
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Guidance
|
||||||
|
//
|
||||||
|
// If you aren't sure what function you need, use SHAKE256 with at least 64
|
||||||
|
// bytes of output. The SHAKE instances are faster than the SHA3 instances;
|
||||||
|
// the latter have to allocate memory to conform to the hash.Hash interface.
|
||||||
|
//
|
||||||
|
// If you need a secret-key MAC (message authentication code), prepend the
|
||||||
|
// secret key to the input, hash with SHAKE256 and read at least 32 bytes of
|
||||||
|
// output.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Security strengths
|
||||||
|
//
|
||||||
|
// The SHA3-x (x equals 224, 256, 384, or 512) functions have a security
|
||||||
|
// strength against preimage attacks of x bits. Since they only produce "x"
|
||||||
|
// bits of output, their collision-resistance is only "x/2" bits.
|
||||||
|
//
|
||||||
|
// The SHAKE-256 and -128 functions have a generic security strength of 256 and
|
||||||
|
// 128 bits against all attacks, provided that at least 2x bits of their output
|
||||||
|
// is used. Requesting more than 64 or 32 bytes of output, respectively, does
|
||||||
|
// not increase the collision-resistance of the SHAKE functions.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// The sponge construction
|
||||||
|
//
|
||||||
|
// A sponge builds a pseudo-random function from a public pseudo-random
|
||||||
|
// permutation, by applying the permutation to a state of "rate + capacity"
|
||||||
|
// bytes, but hiding "capacity" of the bytes.
|
||||||
|
//
|
||||||
|
// A sponge starts out with a zero state. To hash an input using a sponge, up
|
||||||
|
// to "rate" bytes of the input are XORed into the sponge's state. The sponge
|
||||||
|
// is then "full" and the permutation is applied to "empty" it. This process is
|
||||||
|
// repeated until all the input has been "absorbed". The input is then padded.
|
||||||
|
// The digest is "squeezed" from the sponge in the same way, except that output
|
||||||
|
// is copied out instead of input being XORed in.
|
||||||
|
//
|
||||||
|
// A sponge is parameterized by its generic security strength, which is equal
|
||||||
|
// to half its capacity; capacity + rate is equal to the permutation's width.
|
||||||
|
// Since the KeccakF-1600 permutation is 1600 bits (200 bytes) wide, this means
|
||||||
|
// that the security strength of a sponge instance is equal to (1600 - bitrate) / 2.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Recommendations
|
||||||
|
//
|
||||||
|
// The SHAKE functions are recommended for most new uses. They can produce
|
||||||
|
// output of arbitrary length. SHAKE256, with an output length of at least
|
||||||
|
// 64 bytes, provides 256-bit security against all attacks. The Keccak team
|
||||||
|
// recommends it for most applications upgrading from SHA2-512. (NIST chose a
|
||||||
|
// much stronger, but much slower, sponge instance for SHA3-512.)
|
||||||
|
//
|
||||||
|
// The SHA-3 functions are "drop-in" replacements for the SHA-2 functions.
|
||||||
|
// They produce output of the same length, with the same security strengths
|
||||||
|
// against all attacks. This means, in particular, that SHA3-256 only has
|
||||||
|
// 128-bit collision resistance, because its output length is 32 bytes.
|
||||||
|
package sha3 // import "golang.org/x/crypto/sha3"
|
97
vendor/golang.org/x/crypto/sha3/hashes.go
generated
vendored
Normal file
97
vendor/golang.org/x/crypto/sha3/hashes.go
generated
vendored
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package sha3
|
||||||
|
|
||||||
|
// This file provides functions for creating instances of the SHA-3
|
||||||
|
// and SHAKE hash functions, as well as utility functions for hashing
|
||||||
|
// bytes.
|
||||||
|
|
||||||
|
import (
|
||||||
|
"hash"
|
||||||
|
)
|
||||||
|
|
||||||
|
// New224 creates a new SHA3-224 hash.
|
||||||
|
// Its generic security strength is 224 bits against preimage attacks,
|
||||||
|
// and 112 bits against collision attacks.
|
||||||
|
func New224() hash.Hash {
|
||||||
|
if h := new224Asm(); h != nil {
|
||||||
|
return h
|
||||||
|
}
|
||||||
|
return &state{rate: 144, outputLen: 28, dsbyte: 0x06}
|
||||||
|
}
|
||||||
|
|
||||||
|
// New256 creates a new SHA3-256 hash.
|
||||||
|
// Its generic security strength is 256 bits against preimage attacks,
|
||||||
|
// and 128 bits against collision attacks.
|
||||||
|
func New256() hash.Hash {
|
||||||
|
if h := new256Asm(); h != nil {
|
||||||
|
return h
|
||||||
|
}
|
||||||
|
return &state{rate: 136, outputLen: 32, dsbyte: 0x06}
|
||||||
|
}
|
||||||
|
|
||||||
|
// New384 creates a new SHA3-384 hash.
|
||||||
|
// Its generic security strength is 384 bits against preimage attacks,
|
||||||
|
// and 192 bits against collision attacks.
|
||||||
|
func New384() hash.Hash {
|
||||||
|
if h := new384Asm(); h != nil {
|
||||||
|
return h
|
||||||
|
}
|
||||||
|
return &state{rate: 104, outputLen: 48, dsbyte: 0x06}
|
||||||
|
}
|
||||||
|
|
||||||
|
// New512 creates a new SHA3-512 hash.
|
||||||
|
// Its generic security strength is 512 bits against preimage attacks,
|
||||||
|
// and 256 bits against collision attacks.
|
||||||
|
func New512() hash.Hash {
|
||||||
|
if h := new512Asm(); h != nil {
|
||||||
|
return h
|
||||||
|
}
|
||||||
|
return &state{rate: 72, outputLen: 64, dsbyte: 0x06}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewLegacyKeccak256 creates a new Keccak-256 hash.
|
||||||
|
//
|
||||||
|
// Only use this function if you require compatibility with an existing cryptosystem
|
||||||
|
// that uses non-standard padding. All other users should use New256 instead.
|
||||||
|
func NewLegacyKeccak256() hash.Hash { return &state{rate: 136, outputLen: 32, dsbyte: 0x01} }
|
||||||
|
|
||||||
|
// NewLegacyKeccak512 creates a new Keccak-512 hash.
|
||||||
|
//
|
||||||
|
// Only use this function if you require compatibility with an existing cryptosystem
|
||||||
|
// that uses non-standard padding. All other users should use New512 instead.
|
||||||
|
func NewLegacyKeccak512() hash.Hash { return &state{rate: 72, outputLen: 64, dsbyte: 0x01} }
|
||||||
|
|
||||||
|
// Sum224 returns the SHA3-224 digest of the data.
|
||||||
|
func Sum224(data []byte) (digest [28]byte) {
|
||||||
|
h := New224()
|
||||||
|
h.Write(data)
|
||||||
|
h.Sum(digest[:0])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sum256 returns the SHA3-256 digest of the data.
|
||||||
|
func Sum256(data []byte) (digest [32]byte) {
|
||||||
|
h := New256()
|
||||||
|
h.Write(data)
|
||||||
|
h.Sum(digest[:0])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sum384 returns the SHA3-384 digest of the data.
|
||||||
|
func Sum384(data []byte) (digest [48]byte) {
|
||||||
|
h := New384()
|
||||||
|
h.Write(data)
|
||||||
|
h.Sum(digest[:0])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sum512 returns the SHA3-512 digest of the data.
|
||||||
|
func Sum512(data []byte) (digest [64]byte) {
|
||||||
|
h := New512()
|
||||||
|
h.Write(data)
|
||||||
|
h.Sum(digest[:0])
|
||||||
|
return
|
||||||
|
}
|
27
vendor/golang.org/x/crypto/sha3/hashes_generic.go
generated
vendored
Normal file
27
vendor/golang.org/x/crypto/sha3/hashes_generic.go
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
// Copyright 2017 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build gccgo appengine !s390x
|
||||||
|
|
||||||
|
package sha3
|
||||||
|
|
||||||
|
import (
|
||||||
|
"hash"
|
||||||
|
)
|
||||||
|
|
||||||
|
// new224Asm returns an assembly implementation of SHA3-224 if available,
|
||||||
|
// otherwise it returns nil.
|
||||||
|
func new224Asm() hash.Hash { return nil }
|
||||||
|
|
||||||
|
// new256Asm returns an assembly implementation of SHA3-256 if available,
|
||||||
|
// otherwise it returns nil.
|
||||||
|
func new256Asm() hash.Hash { return nil }
|
||||||
|
|
||||||
|
// new384Asm returns an assembly implementation of SHA3-384 if available,
|
||||||
|
// otherwise it returns nil.
|
||||||
|
func new384Asm() hash.Hash { return nil }
|
||||||
|
|
||||||
|
// new512Asm returns an assembly implementation of SHA3-512 if available,
|
||||||
|
// otherwise it returns nil.
|
||||||
|
func new512Asm() hash.Hash { return nil }
|
412
vendor/golang.org/x/crypto/sha3/keccakf.go
generated
vendored
Normal file
412
vendor/golang.org/x/crypto/sha3/keccakf.go
generated
vendored
Normal file
@ -0,0 +1,412 @@
|
|||||||
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !amd64 appengine gccgo
|
||||||
|
|
||||||
|
package sha3
|
||||||
|
|
||||||
|
// rc stores the round constants for use in the ι step.
|
||||||
|
var rc = [24]uint64{
|
||||||
|
0x0000000000000001,
|
||||||
|
0x0000000000008082,
|
||||||
|
0x800000000000808A,
|
||||||
|
0x8000000080008000,
|
||||||
|
0x000000000000808B,
|
||||||
|
0x0000000080000001,
|
||||||
|
0x8000000080008081,
|
||||||
|
0x8000000000008009,
|
||||||
|
0x000000000000008A,
|
||||||
|
0x0000000000000088,
|
||||||
|
0x0000000080008009,
|
||||||
|
0x000000008000000A,
|
||||||
|
0x000000008000808B,
|
||||||
|
0x800000000000008B,
|
||||||
|
0x8000000000008089,
|
||||||
|
0x8000000000008003,
|
||||||
|
0x8000000000008002,
|
||||||
|
0x8000000000000080,
|
||||||
|
0x000000000000800A,
|
||||||
|
0x800000008000000A,
|
||||||
|
0x8000000080008081,
|
||||||
|
0x8000000000008080,
|
||||||
|
0x0000000080000001,
|
||||||
|
0x8000000080008008,
|
||||||
|
}
|
||||||
|
|
||||||
|
// keccakF1600 applies the Keccak permutation to a 1600b-wide
|
||||||
|
// state represented as a slice of 25 uint64s.
|
||||||
|
func keccakF1600(a *[25]uint64) {
|
||||||
|
// Implementation translated from Keccak-inplace.c
|
||||||
|
// in the keccak reference code.
|
||||||
|
var t, bc0, bc1, bc2, bc3, bc4, d0, d1, d2, d3, d4 uint64
|
||||||
|
|
||||||
|
for i := 0; i < 24; i += 4 {
|
||||||
|
// Combines the 5 steps in each round into 2 steps.
|
||||||
|
// Unrolls 4 rounds per loop and spreads some steps across rounds.
|
||||||
|
|
||||||
|
// Round 1
|
||||||
|
bc0 = a[0] ^ a[5] ^ a[10] ^ a[15] ^ a[20]
|
||||||
|
bc1 = a[1] ^ a[6] ^ a[11] ^ a[16] ^ a[21]
|
||||||
|
bc2 = a[2] ^ a[7] ^ a[12] ^ a[17] ^ a[22]
|
||||||
|
bc3 = a[3] ^ a[8] ^ a[13] ^ a[18] ^ a[23]
|
||||||
|
bc4 = a[4] ^ a[9] ^ a[14] ^ a[19] ^ a[24]
|
||||||
|
d0 = bc4 ^ (bc1<<1 | bc1>>63)
|
||||||
|
d1 = bc0 ^ (bc2<<1 | bc2>>63)
|
||||||
|
d2 = bc1 ^ (bc3<<1 | bc3>>63)
|
||||||
|
d3 = bc2 ^ (bc4<<1 | bc4>>63)
|
||||||
|
d4 = bc3 ^ (bc0<<1 | bc0>>63)
|
||||||
|
|
||||||
|
bc0 = a[0] ^ d0
|
||||||
|
t = a[6] ^ d1
|
||||||
|
bc1 = t<<44 | t>>(64-44)
|
||||||
|
t = a[12] ^ d2
|
||||||
|
bc2 = t<<43 | t>>(64-43)
|
||||||
|
t = a[18] ^ d3
|
||||||
|
bc3 = t<<21 | t>>(64-21)
|
||||||
|
t = a[24] ^ d4
|
||||||
|
bc4 = t<<14 | t>>(64-14)
|
||||||
|
a[0] = bc0 ^ (bc2 &^ bc1) ^ rc[i]
|
||||||
|
a[6] = bc1 ^ (bc3 &^ bc2)
|
||||||
|
a[12] = bc2 ^ (bc4 &^ bc3)
|
||||||
|
a[18] = bc3 ^ (bc0 &^ bc4)
|
||||||
|
a[24] = bc4 ^ (bc1 &^ bc0)
|
||||||
|
|
||||||
|
t = a[10] ^ d0
|
||||||
|
bc2 = t<<3 | t>>(64-3)
|
||||||
|
t = a[16] ^ d1
|
||||||
|
bc3 = t<<45 | t>>(64-45)
|
||||||
|
t = a[22] ^ d2
|
||||||
|
bc4 = t<<61 | t>>(64-61)
|
||||||
|
t = a[3] ^ d3
|
||||||
|
bc0 = t<<28 | t>>(64-28)
|
||||||
|
t = a[9] ^ d4
|
||||||
|
bc1 = t<<20 | t>>(64-20)
|
||||||
|
a[10] = bc0 ^ (bc2 &^ bc1)
|
||||||
|
a[16] = bc1 ^ (bc3 &^ bc2)
|
||||||
|
a[22] = bc2 ^ (bc4 &^ bc3)
|
||||||
|
a[3] = bc3 ^ (bc0 &^ bc4)
|
||||||
|
a[9] = bc4 ^ (bc1 &^ bc0)
|
||||||
|
|
||||||
|
t = a[20] ^ d0
|
||||||
|
bc4 = t<<18 | t>>(64-18)
|
||||||
|
t = a[1] ^ d1
|
||||||
|
bc0 = t<<1 | t>>(64-1)
|
||||||
|
t = a[7] ^ d2
|
||||||
|
bc1 = t<<6 | t>>(64-6)
|
||||||
|
t = a[13] ^ d3
|
||||||
|
bc2 = t<<25 | t>>(64-25)
|
||||||
|
t = a[19] ^ d4
|
||||||
|
bc3 = t<<8 | t>>(64-8)
|
||||||
|
a[20] = bc0 ^ (bc2 &^ bc1)
|
||||||
|
a[1] = bc1 ^ (bc3 &^ bc2)
|
||||||
|
a[7] = bc2 ^ (bc4 &^ bc3)
|
||||||
|
a[13] = bc3 ^ (bc0 &^ bc4)
|
||||||
|
a[19] = bc4 ^ (bc1 &^ bc0)
|
||||||
|
|
||||||
|
t = a[5] ^ d0
|
||||||
|
bc1 = t<<36 | t>>(64-36)
|
||||||
|
t = a[11] ^ d1
|
||||||
|
bc2 = t<<10 | t>>(64-10)
|
||||||
|
t = a[17] ^ d2
|
||||||
|
bc3 = t<<15 | t>>(64-15)
|
||||||
|
t = a[23] ^ d3
|
||||||
|
bc4 = t<<56 | t>>(64-56)
|
||||||
|
t = a[4] ^ d4
|
||||||
|
bc0 = t<<27 | t>>(64-27)
|
||||||
|
a[5] = bc0 ^ (bc2 &^ bc1)
|
||||||
|
a[11] = bc1 ^ (bc3 &^ bc2)
|
||||||
|
a[17] = bc2 ^ (bc4 &^ bc3)
|
||||||
|
a[23] = bc3 ^ (bc0 &^ bc4)
|
||||||
|
a[4] = bc4 ^ (bc1 &^ bc0)
|
||||||
|
|
||||||
|
t = a[15] ^ d0
|
||||||
|
bc3 = t<<41 | t>>(64-41)
|
||||||
|
t = a[21] ^ d1
|
||||||
|
bc4 = t<<2 | t>>(64-2)
|
||||||
|
t = a[2] ^ d2
|
||||||
|
bc0 = t<<62 | t>>(64-62)
|
||||||
|
t = a[8] ^ d3
|
||||||
|
bc1 = t<<55 | t>>(64-55)
|
||||||
|
t = a[14] ^ d4
|
||||||
|
bc2 = t<<39 | t>>(64-39)
|
||||||
|
a[15] = bc0 ^ (bc2 &^ bc1)
|
||||||
|
a[21] = bc1 ^ (bc3 &^ bc2)
|
||||||
|
a[2] = bc2 ^ (bc4 &^ bc3)
|
||||||
|
a[8] = bc3 ^ (bc0 &^ bc4)
|
||||||
|
a[14] = bc4 ^ (bc1 &^ bc0)
|
||||||
|
|
||||||
|
// Round 2
|
||||||
|
bc0 = a[0] ^ a[5] ^ a[10] ^ a[15] ^ a[20]
|
||||||
|
bc1 = a[1] ^ a[6] ^ a[11] ^ a[16] ^ a[21]
|
||||||
|
bc2 = a[2] ^ a[7] ^ a[12] ^ a[17] ^ a[22]
|
||||||
|
bc3 = a[3] ^ a[8] ^ a[13] ^ a[18] ^ a[23]
|
||||||
|
bc4 = a[4] ^ a[9] ^ a[14] ^ a[19] ^ a[24]
|
||||||
|
d0 = bc4 ^ (bc1<<1 | bc1>>63)
|
||||||
|
d1 = bc0 ^ (bc2<<1 | bc2>>63)
|
||||||
|
d2 = bc1 ^ (bc3<<1 | bc3>>63)
|
||||||
|
d3 = bc2 ^ (bc4<<1 | bc4>>63)
|
||||||
|
d4 = bc3 ^ (bc0<<1 | bc0>>63)
|
||||||
|
|
||||||
|
bc0 = a[0] ^ d0
|
||||||
|
t = a[16] ^ d1
|
||||||
|
bc1 = t<<44 | t>>(64-44)
|
||||||
|
t = a[7] ^ d2
|
||||||
|
bc2 = t<<43 | t>>(64-43)
|
||||||
|
t = a[23] ^ d3
|
||||||
|
bc3 = t<<21 | t>>(64-21)
|
||||||
|
t = a[14] ^ d4
|
||||||
|
bc4 = t<<14 | t>>(64-14)
|
||||||
|
a[0] = bc0 ^ (bc2 &^ bc1) ^ rc[i+1]
|
||||||
|
a[16] = bc1 ^ (bc3 &^ bc2)
|
||||||
|
a[7] = bc2 ^ (bc4 &^ bc3)
|
||||||
|
a[23] = bc3 ^ (bc0 &^ bc4)
|
||||||
|
a[14] = bc4 ^ (bc1 &^ bc0)
|
||||||
|
|
||||||
|
t = a[20] ^ d0
|
||||||
|
bc2 = t<<3 | t>>(64-3)
|
||||||
|
t = a[11] ^ d1
|
||||||
|
bc3 = t<<45 | t>>(64-45)
|
||||||
|
t = a[2] ^ d2
|
||||||
|
bc4 = t<<61 | t>>(64-61)
|
||||||
|
t = a[18] ^ d3
|
||||||
|
bc0 = t<<28 | t>>(64-28)
|
||||||
|
t = a[9] ^ d4
|
||||||
|
bc1 = t<<20 | t>>(64-20)
|
||||||
|
a[20] = bc0 ^ (bc2 &^ bc1)
|
||||||
|
a[11] = bc1 ^ (bc3 &^ bc2)
|
||||||
|
a[2] = bc2 ^ (bc4 &^ bc3)
|
||||||
|
a[18] = bc3 ^ (bc0 &^ bc4)
|
||||||
|
a[9] = bc4 ^ (bc1 &^ bc0)
|
||||||
|
|
||||||
|
t = a[15] ^ d0
|
||||||
|
bc4 = t<<18 | t>>(64-18)
|
||||||
|
t = a[6] ^ d1
|
||||||
|
bc0 = t<<1 | t>>(64-1)
|
||||||
|
t = a[22] ^ d2
|
||||||
|
bc1 = t<<6 | t>>(64-6)
|
||||||
|
t = a[13] ^ d3
|
||||||
|
bc2 = t<<25 | t>>(64-25)
|
||||||
|
t = a[4] ^ d4
|
||||||
|
bc3 = t<<8 | t>>(64-8)
|
||||||
|
a[15] = bc0 ^ (bc2 &^ bc1)
|
||||||
|
a[6] = bc1 ^ (bc3 &^ bc2)
|
||||||
|
a[22] = bc2 ^ (bc4 &^ bc3)
|
||||||
|
a[13] = bc3 ^ (bc0 &^ bc4)
|
||||||
|
a[4] = bc4 ^ (bc1 &^ bc0)
|
||||||
|
|
||||||
|
t = a[10] ^ d0
|
||||||
|
bc1 = t<<36 | t>>(64-36)
|
||||||
|
t = a[1] ^ d1
|
||||||
|
bc2 = t<<10 | t>>(64-10)
|
||||||
|
t = a[17] ^ d2
|
||||||
|
bc3 = t<<15 | t>>(64-15)
|
||||||
|
t = a[8] ^ d3
|
||||||
|
bc4 = t<<56 | t>>(64-56)
|
||||||
|
t = a[24] ^ d4
|
||||||
|
bc0 = t<<27 | t>>(64-27)
|
||||||
|
a[10] = bc0 ^ (bc2 &^ bc1)
|
||||||
|
a[1] = bc1 ^ (bc3 &^ bc2)
|
||||||
|
a[17] = bc2 ^ (bc4 &^ bc3)
|
||||||
|
a[8] = bc3 ^ (bc0 &^ bc4)
|
||||||
|
a[24] = bc4 ^ (bc1 &^ bc0)
|
||||||
|
|
||||||
|
t = a[5] ^ d0
|
||||||
|
bc3 = t<<41 | t>>(64-41)
|
||||||
|
t = a[21] ^ d1
|
||||||
|
bc4 = t<<2 | t>>(64-2)
|
||||||
|
t = a[12] ^ d2
|
||||||
|
bc0 = t<<62 | t>>(64-62)
|
||||||
|
t = a[3] ^ d3
|
||||||
|
bc1 = t<<55 | t>>(64-55)
|
||||||
|
t = a[19] ^ d4
|
||||||
|
bc2 = t<<39 | t>>(64-39)
|
||||||
|
a[5] = bc0 ^ (bc2 &^ bc1)
|
||||||
|
a[21] = bc1 ^ (bc3 &^ bc2)
|
||||||
|
a[12] = bc2 ^ (bc4 &^ bc3)
|
||||||
|
a[3] = bc3 ^ (bc0 &^ bc4)
|
||||||
|
a[19] = bc4 ^ (bc1 &^ bc0)
|
||||||
|
|
||||||
|
// Round 3
|
||||||
|
bc0 = a[0] ^ a[5] ^ a[10] ^ a[15] ^ a[20]
|
||||||
|
bc1 = a[1] ^ a[6] ^ a[11] ^ a[16] ^ a[21]
|
||||||
|
bc2 = a[2] ^ a[7] ^ a[12] ^ a[17] ^ a[22]
|
||||||
|
bc3 = a[3] ^ a[8] ^ a[13] ^ a[18] ^ a[23]
|
||||||
|
bc4 = a[4] ^ a[9] ^ a[14] ^ a[19] ^ a[24]
|
||||||
|
d0 = bc4 ^ (bc1<<1 | bc1>>63)
|
||||||
|
d1 = bc0 ^ (bc2<<1 | bc2>>63)
|
||||||
|
d2 = bc1 ^ (bc3<<1 | bc3>>63)
|
||||||
|
d3 = bc2 ^ (bc4<<1 | bc4>>63)
|
||||||
|
d4 = bc3 ^ (bc0<<1 | bc0>>63)
|
||||||
|
|
||||||
|
bc0 = a[0] ^ d0
|
||||||
|
t = a[11] ^ d1
|
||||||
|
bc1 = t<<44 | t>>(64-44)
|
||||||
|
t = a[22] ^ d2
|
||||||
|
bc2 = t<<43 | t>>(64-43)
|
||||||
|
t = a[8] ^ d3
|
||||||
|
bc3 = t<<21 | t>>(64-21)
|
||||||
|
t = a[19] ^ d4
|
||||||
|
bc4 = t<<14 | t>>(64-14)
|
||||||
|
a[0] = bc0 ^ (bc2 &^ bc1) ^ rc[i+2]
|
||||||
|
a[11] = bc1 ^ (bc3 &^ bc2)
|
||||||
|
a[22] = bc2 ^ (bc4 &^ bc3)
|
||||||
|
a[8] = bc3 ^ (bc0 &^ bc4)
|
||||||
|
a[19] = bc4 ^ (bc1 &^ bc0)
|
||||||
|
|
||||||
|
t = a[15] ^ d0
|
||||||
|
bc2 = t<<3 | t>>(64-3)
|
||||||
|
t = a[1] ^ d1
|
||||||
|
bc3 = t<<45 | t>>(64-45)
|
||||||
|
t = a[12] ^ d2
|
||||||
|
bc4 = t<<61 | t>>(64-61)
|
||||||
|
t = a[23] ^ d3
|
||||||
|
bc0 = t<<28 | t>>(64-28)
|
||||||
|
t = a[9] ^ d4
|
||||||
|
bc1 = t<<20 | t>>(64-20)
|
||||||
|
a[15] = bc0 ^ (bc2 &^ bc1)
|
||||||
|
a[1] = bc1 ^ (bc3 &^ bc2)
|
||||||
|
a[12] = bc2 ^ (bc4 &^ bc3)
|
||||||
|
a[23] = bc3 ^ (bc0 &^ bc4)
|
||||||
|
a[9] = bc4 ^ (bc1 &^ bc0)
|
||||||
|
|
||||||
|
t = a[5] ^ d0
|
||||||
|
bc4 = t<<18 | t>>(64-18)
|
||||||
|
t = a[16] ^ d1
|
||||||
|
bc0 = t<<1 | t>>(64-1)
|
||||||
|
t = a[2] ^ d2
|
||||||
|
bc1 = t<<6 | t>>(64-6)
|
||||||
|
t = a[13] ^ d3
|
||||||
|
bc2 = t<<25 | t>>(64-25)
|
||||||
|
t = a[24] ^ d4
|
||||||
|
bc3 = t<<8 | t>>(64-8)
|
||||||
|
a[5] = bc0 ^ (bc2 &^ bc1)
|
||||||
|
a[16] = bc1 ^ (bc3 &^ bc2)
|
||||||
|
a[2] = bc2 ^ (bc4 &^ bc3)
|
||||||
|
a[13] = bc3 ^ (bc0 &^ bc4)
|
||||||
|
a[24] = bc4 ^ (bc1 &^ bc0)
|
||||||
|
|
||||||
|
t = a[20] ^ d0
|
||||||
|
bc1 = t<<36 | t>>(64-36)
|
||||||
|
t = a[6] ^ d1
|
||||||
|
bc2 = t<<10 | t>>(64-10)
|
||||||
|
t = a[17] ^ d2
|
||||||
|
bc3 = t<<15 | t>>(64-15)
|
||||||
|
t = a[3] ^ d3
|
||||||
|
bc4 = t<<56 | t>>(64-56)
|
||||||
|
t = a[14] ^ d4
|
||||||
|
bc0 = t<<27 | t>>(64-27)
|
||||||
|
a[20] = bc0 ^ (bc2 &^ bc1)
|
||||||
|
a[6] = bc1 ^ (bc3 &^ bc2)
|
||||||
|
a[17] = bc2 ^ (bc4 &^ bc3)
|
||||||
|
a[3] = bc3 ^ (bc0 &^ bc4)
|
||||||
|
a[14] = bc4 ^ (bc1 &^ bc0)
|
||||||
|
|
||||||
|
t = a[10] ^ d0
|
||||||
|
bc3 = t<<41 | t>>(64-41)
|
||||||
|
t = a[21] ^ d1
|
||||||
|
bc4 = t<<2 | t>>(64-2)
|
||||||
|
t = a[7] ^ d2
|
||||||
|
bc0 = t<<62 | t>>(64-62)
|
||||||
|
t = a[18] ^ d3
|
||||||
|
bc1 = t<<55 | t>>(64-55)
|
||||||
|
t = a[4] ^ d4
|
||||||
|
bc2 = t<<39 | t>>(64-39)
|
||||||
|
a[10] = bc0 ^ (bc2 &^ bc1)
|
||||||
|
a[21] = bc1 ^ (bc3 &^ bc2)
|
||||||
|
a[7] = bc2 ^ (bc4 &^ bc3)
|
||||||
|
a[18] = bc3 ^ (bc0 &^ bc4)
|
||||||
|
a[4] = bc4 ^ (bc1 &^ bc0)
|
||||||
|
|
||||||
|
// Round 4
|
||||||
|
bc0 = a[0] ^ a[5] ^ a[10] ^ a[15] ^ a[20]
|
||||||
|
bc1 = a[1] ^ a[6] ^ a[11] ^ a[16] ^ a[21]
|
||||||
|
bc2 = a[2] ^ a[7] ^ a[12] ^ a[17] ^ a[22]
|
||||||
|
bc3 = a[3] ^ a[8] ^ a[13] ^ a[18] ^ a[23]
|
||||||
|
bc4 = a[4] ^ a[9] ^ a[14] ^ a[19] ^ a[24]
|
||||||
|
d0 = bc4 ^ (bc1<<1 | bc1>>63)
|
||||||
|
d1 = bc0 ^ (bc2<<1 | bc2>>63)
|
||||||
|
d2 = bc1 ^ (bc3<<1 | bc3>>63)
|
||||||
|
d3 = bc2 ^ (bc4<<1 | bc4>>63)
|
||||||
|
d4 = bc3 ^ (bc0<<1 | bc0>>63)
|
||||||
|
|
||||||
|
bc0 = a[0] ^ d0
|
||||||
|
t = a[1] ^ d1
|
||||||
|
bc1 = t<<44 | t>>(64-44)
|
||||||
|
t = a[2] ^ d2
|
||||||
|
bc2 = t<<43 | t>>(64-43)
|
||||||
|
t = a[3] ^ d3
|
||||||
|
bc3 = t<<21 | t>>(64-21)
|
||||||
|
t = a[4] ^ d4
|
||||||
|
bc4 = t<<14 | t>>(64-14)
|
||||||
|
a[0] = bc0 ^ (bc2 &^ bc1) ^ rc[i+3]
|
||||||
|
a[1] = bc1 ^ (bc3 &^ bc2)
|
||||||
|
a[2] = bc2 ^ (bc4 &^ bc3)
|
||||||
|
a[3] = bc3 ^ (bc0 &^ bc4)
|
||||||
|
a[4] = bc4 ^ (bc1 &^ bc0)
|
||||||
|
|
||||||
|
t = a[5] ^ d0
|
||||||
|
bc2 = t<<3 | t>>(64-3)
|
||||||
|
t = a[6] ^ d1
|
||||||
|
bc3 = t<<45 | t>>(64-45)
|
||||||
|
t = a[7] ^ d2
|
||||||
|
bc4 = t<<61 | t>>(64-61)
|
||||||
|
t = a[8] ^ d3
|
||||||
|
bc0 = t<<28 | t>>(64-28)
|
||||||
|
t = a[9] ^ d4
|
||||||
|
bc1 = t<<20 | t>>(64-20)
|
||||||
|
a[5] = bc0 ^ (bc2 &^ bc1)
|
||||||
|
a[6] = bc1 ^ (bc3 &^ bc2)
|
||||||
|
a[7] = bc2 ^ (bc4 &^ bc3)
|
||||||
|
a[8] = bc3 ^ (bc0 &^ bc4)
|
||||||
|
a[9] = bc4 ^ (bc1 &^ bc0)
|
||||||
|
|
||||||
|
t = a[10] ^ d0
|
||||||
|
bc4 = t<<18 | t>>(64-18)
|
||||||
|
t = a[11] ^ d1
|
||||||
|
bc0 = t<<1 | t>>(64-1)
|
||||||
|
t = a[12] ^ d2
|
||||||
|
bc1 = t<<6 | t>>(64-6)
|
||||||
|
t = a[13] ^ d3
|
||||||
|
bc2 = t<<25 | t>>(64-25)
|
||||||
|
t = a[14] ^ d4
|
||||||
|
bc3 = t<<8 | t>>(64-8)
|
||||||
|
a[10] = bc0 ^ (bc2 &^ bc1)
|
||||||
|
a[11] = bc1 ^ (bc3 &^ bc2)
|
||||||
|
a[12] = bc2 ^ (bc4 &^ bc3)
|
||||||
|
a[13] = bc3 ^ (bc0 &^ bc4)
|
||||||
|
a[14] = bc4 ^ (bc1 &^ bc0)
|
||||||
|
|
||||||
|
t = a[15] ^ d0
|
||||||
|
bc1 = t<<36 | t>>(64-36)
|
||||||
|
t = a[16] ^ d1
|
||||||
|
bc2 = t<<10 | t>>(64-10)
|
||||||
|
t = a[17] ^ d2
|
||||||
|
bc3 = t<<15 | t>>(64-15)
|
||||||
|
t = a[18] ^ d3
|
||||||
|
bc4 = t<<56 | t>>(64-56)
|
||||||
|
t = a[19] ^ d4
|
||||||
|
bc0 = t<<27 | t>>(64-27)
|
||||||
|
a[15] = bc0 ^ (bc2 &^ bc1)
|
||||||
|
a[16] = bc1 ^ (bc3 &^ bc2)
|
||||||
|
a[17] = bc2 ^ (bc4 &^ bc3)
|
||||||
|
a[18] = bc3 ^ (bc0 &^ bc4)
|
||||||
|
a[19] = bc4 ^ (bc1 &^ bc0)
|
||||||
|
|
||||||
|
t = a[20] ^ d0
|
||||||
|
bc3 = t<<41 | t>>(64-41)
|
||||||
|
t = a[21] ^ d1
|
||||||
|
bc4 = t<<2 | t>>(64-2)
|
||||||
|
t = a[22] ^ d2
|
||||||
|
bc0 = t<<62 | t>>(64-62)
|
||||||
|
t = a[23] ^ d3
|
||||||
|
bc1 = t<<55 | t>>(64-55)
|
||||||
|
t = a[24] ^ d4
|
||||||
|
bc2 = t<<39 | t>>(64-39)
|
||||||
|
a[20] = bc0 ^ (bc2 &^ bc1)
|
||||||
|
a[21] = bc1 ^ (bc3 &^ bc2)
|
||||||
|
a[22] = bc2 ^ (bc4 &^ bc3)
|
||||||
|
a[23] = bc3 ^ (bc0 &^ bc4)
|
||||||
|
a[24] = bc4 ^ (bc1 &^ bc0)
|
||||||
|
}
|
||||||
|
}
|
13
vendor/golang.org/x/crypto/sha3/keccakf_amd64.go
generated
vendored
Normal file
13
vendor/golang.org/x/crypto/sha3/keccakf_amd64.go
generated
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
// Copyright 2015 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build amd64,!appengine,!gccgo
|
||||||
|
|
||||||
|
package sha3
|
||||||
|
|
||||||
|
// This function is implemented in keccakf_amd64.s.
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
|
||||||
|
func keccakF1600(a *[25]uint64)
|
390
vendor/golang.org/x/crypto/sha3/keccakf_amd64.s
generated
vendored
Normal file
390
vendor/golang.org/x/crypto/sha3/keccakf_amd64.s
generated
vendored
Normal file
@ -0,0 +1,390 @@
|
|||||||
|
// Copyright 2015 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build amd64,!appengine,!gccgo
|
||||||
|
|
||||||
|
// This code was translated into a form compatible with 6a from the public
|
||||||
|
// domain sources at https://github.com/gvanas/KeccakCodePackage
|
||||||
|
|
||||||
|
// Offsets in state
|
||||||
|
#define _ba (0*8)
|
||||||
|
#define _be (1*8)
|
||||||
|
#define _bi (2*8)
|
||||||
|
#define _bo (3*8)
|
||||||
|
#define _bu (4*8)
|
||||||
|
#define _ga (5*8)
|
||||||
|
#define _ge (6*8)
|
||||||
|
#define _gi (7*8)
|
||||||
|
#define _go (8*8)
|
||||||
|
#define _gu (9*8)
|
||||||
|
#define _ka (10*8)
|
||||||
|
#define _ke (11*8)
|
||||||
|
#define _ki (12*8)
|
||||||
|
#define _ko (13*8)
|
||||||
|
#define _ku (14*8)
|
||||||
|
#define _ma (15*8)
|
||||||
|
#define _me (16*8)
|
||||||
|
#define _mi (17*8)
|
||||||
|
#define _mo (18*8)
|
||||||
|
#define _mu (19*8)
|
||||||
|
#define _sa (20*8)
|
||||||
|
#define _se (21*8)
|
||||||
|
#define _si (22*8)
|
||||||
|
#define _so (23*8)
|
||||||
|
#define _su (24*8)
|
||||||
|
|
||||||
|
// Temporary registers
|
||||||
|
#define rT1 AX
|
||||||
|
|
||||||
|
// Round vars
|
||||||
|
#define rpState DI
|
||||||
|
#define rpStack SP
|
||||||
|
|
||||||
|
#define rDa BX
|
||||||
|
#define rDe CX
|
||||||
|
#define rDi DX
|
||||||
|
#define rDo R8
|
||||||
|
#define rDu R9
|
||||||
|
|
||||||
|
#define rBa R10
|
||||||
|
#define rBe R11
|
||||||
|
#define rBi R12
|
||||||
|
#define rBo R13
|
||||||
|
#define rBu R14
|
||||||
|
|
||||||
|
#define rCa SI
|
||||||
|
#define rCe BP
|
||||||
|
#define rCi rBi
|
||||||
|
#define rCo rBo
|
||||||
|
#define rCu R15
|
||||||
|
|
||||||
|
#define MOVQ_RBI_RCE MOVQ rBi, rCe
|
||||||
|
#define XORQ_RT1_RCA XORQ rT1, rCa
|
||||||
|
#define XORQ_RT1_RCE XORQ rT1, rCe
|
||||||
|
#define XORQ_RBA_RCU XORQ rBa, rCu
|
||||||
|
#define XORQ_RBE_RCU XORQ rBe, rCu
|
||||||
|
#define XORQ_RDU_RCU XORQ rDu, rCu
|
||||||
|
#define XORQ_RDA_RCA XORQ rDa, rCa
|
||||||
|
#define XORQ_RDE_RCE XORQ rDe, rCe
|
||||||
|
|
||||||
|
#define mKeccakRound(iState, oState, rc, B_RBI_RCE, G_RT1_RCA, G_RT1_RCE, G_RBA_RCU, K_RT1_RCA, K_RT1_RCE, K_RBA_RCU, M_RT1_RCA, M_RT1_RCE, M_RBE_RCU, S_RDU_RCU, S_RDA_RCA, S_RDE_RCE) \
|
||||||
|
/* Prepare round */ \
|
||||||
|
MOVQ rCe, rDa; \
|
||||||
|
ROLQ $1, rDa; \
|
||||||
|
\
|
||||||
|
MOVQ _bi(iState), rCi; \
|
||||||
|
XORQ _gi(iState), rDi; \
|
||||||
|
XORQ rCu, rDa; \
|
||||||
|
XORQ _ki(iState), rCi; \
|
||||||
|
XORQ _mi(iState), rDi; \
|
||||||
|
XORQ rDi, rCi; \
|
||||||
|
\
|
||||||
|
MOVQ rCi, rDe; \
|
||||||
|
ROLQ $1, rDe; \
|
||||||
|
\
|
||||||
|
MOVQ _bo(iState), rCo; \
|
||||||
|
XORQ _go(iState), rDo; \
|
||||||
|
XORQ rCa, rDe; \
|
||||||
|
XORQ _ko(iState), rCo; \
|
||||||
|
XORQ _mo(iState), rDo; \
|
||||||
|
XORQ rDo, rCo; \
|
||||||
|
\
|
||||||
|
MOVQ rCo, rDi; \
|
||||||
|
ROLQ $1, rDi; \
|
||||||
|
\
|
||||||
|
MOVQ rCu, rDo; \
|
||||||
|
XORQ rCe, rDi; \
|
||||||
|
ROLQ $1, rDo; \
|
||||||
|
\
|
||||||
|
MOVQ rCa, rDu; \
|
||||||
|
XORQ rCi, rDo; \
|
||||||
|
ROLQ $1, rDu; \
|
||||||
|
\
|
||||||
|
/* Result b */ \
|
||||||
|
MOVQ _ba(iState), rBa; \
|
||||||
|
MOVQ _ge(iState), rBe; \
|
||||||
|
XORQ rCo, rDu; \
|
||||||
|
MOVQ _ki(iState), rBi; \
|
||||||
|
MOVQ _mo(iState), rBo; \
|
||||||
|
MOVQ _su(iState), rBu; \
|
||||||
|
XORQ rDe, rBe; \
|
||||||
|
ROLQ $44, rBe; \
|
||||||
|
XORQ rDi, rBi; \
|
||||||
|
XORQ rDa, rBa; \
|
||||||
|
ROLQ $43, rBi; \
|
||||||
|
\
|
||||||
|
MOVQ rBe, rCa; \
|
||||||
|
MOVQ rc, rT1; \
|
||||||
|
ORQ rBi, rCa; \
|
||||||
|
XORQ rBa, rT1; \
|
||||||
|
XORQ rT1, rCa; \
|
||||||
|
MOVQ rCa, _ba(oState); \
|
||||||
|
\
|
||||||
|
XORQ rDu, rBu; \
|
||||||
|
ROLQ $14, rBu; \
|
||||||
|
MOVQ rBa, rCu; \
|
||||||
|
ANDQ rBe, rCu; \
|
||||||
|
XORQ rBu, rCu; \
|
||||||
|
MOVQ rCu, _bu(oState); \
|
||||||
|
\
|
||||||
|
XORQ rDo, rBo; \
|
||||||
|
ROLQ $21, rBo; \
|
||||||
|
MOVQ rBo, rT1; \
|
||||||
|
ANDQ rBu, rT1; \
|
||||||
|
XORQ rBi, rT1; \
|
||||||
|
MOVQ rT1, _bi(oState); \
|
||||||
|
\
|
||||||
|
NOTQ rBi; \
|
||||||
|
ORQ rBa, rBu; \
|
||||||
|
ORQ rBo, rBi; \
|
||||||
|
XORQ rBo, rBu; \
|
||||||
|
XORQ rBe, rBi; \
|
||||||
|
MOVQ rBu, _bo(oState); \
|
||||||
|
MOVQ rBi, _be(oState); \
|
||||||
|
B_RBI_RCE; \
|
||||||
|
\
|
||||||
|
/* Result g */ \
|
||||||
|
MOVQ _gu(iState), rBe; \
|
||||||
|
XORQ rDu, rBe; \
|
||||||
|
MOVQ _ka(iState), rBi; \
|
||||||
|
ROLQ $20, rBe; \
|
||||||
|
XORQ rDa, rBi; \
|
||||||
|
ROLQ $3, rBi; \
|
||||||
|
MOVQ _bo(iState), rBa; \
|
||||||
|
MOVQ rBe, rT1; \
|
||||||
|
ORQ rBi, rT1; \
|
||||||
|
XORQ rDo, rBa; \
|
||||||
|
MOVQ _me(iState), rBo; \
|
||||||
|
MOVQ _si(iState), rBu; \
|
||||||
|
ROLQ $28, rBa; \
|
||||||
|
XORQ rBa, rT1; \
|
||||||
|
MOVQ rT1, _ga(oState); \
|
||||||
|
G_RT1_RCA; \
|
||||||
|
\
|
||||||
|
XORQ rDe, rBo; \
|
||||||
|
ROLQ $45, rBo; \
|
||||||
|
MOVQ rBi, rT1; \
|
||||||
|
ANDQ rBo, rT1; \
|
||||||
|
XORQ rBe, rT1; \
|
||||||
|
MOVQ rT1, _ge(oState); \
|
||||||
|
G_RT1_RCE; \
|
||||||
|
\
|
||||||
|
XORQ rDi, rBu; \
|
||||||
|
ROLQ $61, rBu; \
|
||||||
|
MOVQ rBu, rT1; \
|
||||||
|
ORQ rBa, rT1; \
|
||||||
|
XORQ rBo, rT1; \
|
||||||
|
MOVQ rT1, _go(oState); \
|
||||||
|
\
|
||||||
|
ANDQ rBe, rBa; \
|
||||||
|
XORQ rBu, rBa; \
|
||||||
|
MOVQ rBa, _gu(oState); \
|
||||||
|
NOTQ rBu; \
|
||||||
|
G_RBA_RCU; \
|
||||||
|
\
|
||||||
|
ORQ rBu, rBo; \
|
||||||
|
XORQ rBi, rBo; \
|
||||||
|
MOVQ rBo, _gi(oState); \
|
||||||
|
\
|
||||||
|
/* Result k */ \
|
||||||
|
MOVQ _be(iState), rBa; \
|
||||||
|
MOVQ _gi(iState), rBe; \
|
||||||
|
MOVQ _ko(iState), rBi; \
|
||||||
|
MOVQ _mu(iState), rBo; \
|
||||||
|
MOVQ _sa(iState), rBu; \
|
||||||
|
XORQ rDi, rBe; \
|
||||||
|
ROLQ $6, rBe; \
|
||||||
|
XORQ rDo, rBi; \
|
||||||
|
ROLQ $25, rBi; \
|
||||||
|
MOVQ rBe, rT1; \
|
||||||
|
ORQ rBi, rT1; \
|
||||||
|
XORQ rDe, rBa; \
|
||||||
|
ROLQ $1, rBa; \
|
||||||
|
XORQ rBa, rT1; \
|
||||||
|
MOVQ rT1, _ka(oState); \
|
||||||
|
K_RT1_RCA; \
|
||||||
|
\
|
||||||
|
XORQ rDu, rBo; \
|
||||||
|
ROLQ $8, rBo; \
|
||||||
|
MOVQ rBi, rT1; \
|
||||||
|
ANDQ rBo, rT1; \
|
||||||
|
XORQ rBe, rT1; \
|
||||||
|
MOVQ rT1, _ke(oState); \
|
||||||
|
K_RT1_RCE; \
|
||||||
|
\
|
||||||
|
XORQ rDa, rBu; \
|
||||||
|
ROLQ $18, rBu; \
|
||||||
|
NOTQ rBo; \
|
||||||
|
MOVQ rBo, rT1; \
|
||||||
|
ANDQ rBu, rT1; \
|
||||||
|
XORQ rBi, rT1; \
|
||||||
|
MOVQ rT1, _ki(oState); \
|
||||||
|
\
|
||||||
|
MOVQ rBu, rT1; \
|
||||||
|
ORQ rBa, rT1; \
|
||||||
|
XORQ rBo, rT1; \
|
||||||
|
MOVQ rT1, _ko(oState); \
|
||||||
|
\
|
||||||
|
ANDQ rBe, rBa; \
|
||||||
|
XORQ rBu, rBa; \
|
||||||
|
MOVQ rBa, _ku(oState); \
|
||||||
|
K_RBA_RCU; \
|
||||||
|
\
|
||||||
|
/* Result m */ \
|
||||||
|
MOVQ _ga(iState), rBe; \
|
||||||
|
XORQ rDa, rBe; \
|
||||||
|
MOVQ _ke(iState), rBi; \
|
||||||
|
ROLQ $36, rBe; \
|
||||||
|
XORQ rDe, rBi; \
|
||||||
|
MOVQ _bu(iState), rBa; \
|
||||||
|
ROLQ $10, rBi; \
|
||||||
|
MOVQ rBe, rT1; \
|
||||||
|
MOVQ _mi(iState), rBo; \
|
||||||
|
ANDQ rBi, rT1; \
|
||||||
|
XORQ rDu, rBa; \
|
||||||
|
MOVQ _so(iState), rBu; \
|
||||||
|
ROLQ $27, rBa; \
|
||||||
|
XORQ rBa, rT1; \
|
||||||
|
MOVQ rT1, _ma(oState); \
|
||||||
|
M_RT1_RCA; \
|
||||||
|
\
|
||||||
|
XORQ rDi, rBo; \
|
||||||
|
ROLQ $15, rBo; \
|
||||||
|
MOVQ rBi, rT1; \
|
||||||
|
ORQ rBo, rT1; \
|
||||||
|
XORQ rBe, rT1; \
|
||||||
|
MOVQ rT1, _me(oState); \
|
||||||
|
M_RT1_RCE; \
|
||||||
|
\
|
||||||
|
XORQ rDo, rBu; \
|
||||||
|
ROLQ $56, rBu; \
|
||||||
|
NOTQ rBo; \
|
||||||
|
MOVQ rBo, rT1; \
|
||||||
|
ORQ rBu, rT1; \
|
||||||
|
XORQ rBi, rT1; \
|
||||||
|
MOVQ rT1, _mi(oState); \
|
||||||
|
\
|
||||||
|
ORQ rBa, rBe; \
|
||||||
|
XORQ rBu, rBe; \
|
||||||
|
MOVQ rBe, _mu(oState); \
|
||||||
|
\
|
||||||
|
ANDQ rBa, rBu; \
|
||||||
|
XORQ rBo, rBu; \
|
||||||
|
MOVQ rBu, _mo(oState); \
|
||||||
|
M_RBE_RCU; \
|
||||||
|
\
|
||||||
|
/* Result s */ \
|
||||||
|
MOVQ _bi(iState), rBa; \
|
||||||
|
MOVQ _go(iState), rBe; \
|
||||||
|
MOVQ _ku(iState), rBi; \
|
||||||
|
XORQ rDi, rBa; \
|
||||||
|
MOVQ _ma(iState), rBo; \
|
||||||
|
ROLQ $62, rBa; \
|
||||||
|
XORQ rDo, rBe; \
|
||||||
|
MOVQ _se(iState), rBu; \
|
||||||
|
ROLQ $55, rBe; \
|
||||||
|
\
|
||||||
|
XORQ rDu, rBi; \
|
||||||
|
MOVQ rBa, rDu; \
|
||||||
|
XORQ rDe, rBu; \
|
||||||
|
ROLQ $2, rBu; \
|
||||||
|
ANDQ rBe, rDu; \
|
||||||
|
XORQ rBu, rDu; \
|
||||||
|
MOVQ rDu, _su(oState); \
|
||||||
|
\
|
||||||
|
ROLQ $39, rBi; \
|
||||||
|
S_RDU_RCU; \
|
||||||
|
NOTQ rBe; \
|
||||||
|
XORQ rDa, rBo; \
|
||||||
|
MOVQ rBe, rDa; \
|
||||||
|
ANDQ rBi, rDa; \
|
||||||
|
XORQ rBa, rDa; \
|
||||||
|
MOVQ rDa, _sa(oState); \
|
||||||
|
S_RDA_RCA; \
|
||||||
|
\
|
||||||
|
ROLQ $41, rBo; \
|
||||||
|
MOVQ rBi, rDe; \
|
||||||
|
ORQ rBo, rDe; \
|
||||||
|
XORQ rBe, rDe; \
|
||||||
|
MOVQ rDe, _se(oState); \
|
||||||
|
S_RDE_RCE; \
|
||||||
|
\
|
||||||
|
MOVQ rBo, rDi; \
|
||||||
|
MOVQ rBu, rDo; \
|
||||||
|
ANDQ rBu, rDi; \
|
||||||
|
ORQ rBa, rDo; \
|
||||||
|
XORQ rBi, rDi; \
|
||||||
|
XORQ rBo, rDo; \
|
||||||
|
MOVQ rDi, _si(oState); \
|
||||||
|
MOVQ rDo, _so(oState) \
|
||||||
|
|
||||||
|
// func keccakF1600(state *[25]uint64)
|
||||||
|
TEXT ·keccakF1600(SB), 0, $200-8
|
||||||
|
MOVQ state+0(FP), rpState
|
||||||
|
|
||||||
|
// Convert the user state into an internal state
|
||||||
|
NOTQ _be(rpState)
|
||||||
|
NOTQ _bi(rpState)
|
||||||
|
NOTQ _go(rpState)
|
||||||
|
NOTQ _ki(rpState)
|
||||||
|
NOTQ _mi(rpState)
|
||||||
|
NOTQ _sa(rpState)
|
||||||
|
|
||||||
|
// Execute the KeccakF permutation
|
||||||
|
MOVQ _ba(rpState), rCa
|
||||||
|
MOVQ _be(rpState), rCe
|
||||||
|
MOVQ _bu(rpState), rCu
|
||||||
|
|
||||||
|
XORQ _ga(rpState), rCa
|
||||||
|
XORQ _ge(rpState), rCe
|
||||||
|
XORQ _gu(rpState), rCu
|
||||||
|
|
||||||
|
XORQ _ka(rpState), rCa
|
||||||
|
XORQ _ke(rpState), rCe
|
||||||
|
XORQ _ku(rpState), rCu
|
||||||
|
|
||||||
|
XORQ _ma(rpState), rCa
|
||||||
|
XORQ _me(rpState), rCe
|
||||||
|
XORQ _mu(rpState), rCu
|
||||||
|
|
||||||
|
XORQ _sa(rpState), rCa
|
||||||
|
XORQ _se(rpState), rCe
|
||||||
|
MOVQ _si(rpState), rDi
|
||||||
|
MOVQ _so(rpState), rDo
|
||||||
|
XORQ _su(rpState), rCu
|
||||||
|
|
||||||
|
mKeccakRound(rpState, rpStack, $0x0000000000000001, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpStack, rpState, $0x0000000000008082, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpState, rpStack, $0x800000000000808a, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpStack, rpState, $0x8000000080008000, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpState, rpStack, $0x000000000000808b, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpStack, rpState, $0x0000000080000001, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpState, rpStack, $0x8000000080008081, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpStack, rpState, $0x8000000000008009, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpState, rpStack, $0x000000000000008a, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpStack, rpState, $0x0000000000000088, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpState, rpStack, $0x0000000080008009, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpStack, rpState, $0x000000008000000a, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpState, rpStack, $0x000000008000808b, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpStack, rpState, $0x800000000000008b, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpState, rpStack, $0x8000000000008089, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpStack, rpState, $0x8000000000008003, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpState, rpStack, $0x8000000000008002, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpStack, rpState, $0x8000000000000080, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpState, rpStack, $0x000000000000800a, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpStack, rpState, $0x800000008000000a, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpState, rpStack, $0x8000000080008081, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpStack, rpState, $0x8000000000008080, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpState, rpStack, $0x0000000080000001, MOVQ_RBI_RCE, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBA_RCU, XORQ_RT1_RCA, XORQ_RT1_RCE, XORQ_RBE_RCU, XORQ_RDU_RCU, XORQ_RDA_RCA, XORQ_RDE_RCE)
|
||||||
|
mKeccakRound(rpStack, rpState, $0x8000000080008008, NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP)
|
||||||
|
|
||||||
|
// Revert the internal state to the user state
|
||||||
|
NOTQ _be(rpState)
|
||||||
|
NOTQ _bi(rpState)
|
||||||
|
NOTQ _go(rpState)
|
||||||
|
NOTQ _ki(rpState)
|
||||||
|
NOTQ _mi(rpState)
|
||||||
|
NOTQ _sa(rpState)
|
||||||
|
|
||||||
|
RET
|
18
vendor/golang.org/x/crypto/sha3/register.go
generated
vendored
Normal file
18
vendor/golang.org/x/crypto/sha3/register.go
generated
vendored
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build go1.4
|
||||||
|
|
||||||
|
package sha3
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
crypto.RegisterHash(crypto.SHA3_224, New224)
|
||||||
|
crypto.RegisterHash(crypto.SHA3_256, New256)
|
||||||
|
crypto.RegisterHash(crypto.SHA3_384, New384)
|
||||||
|
crypto.RegisterHash(crypto.SHA3_512, New512)
|
||||||
|
}
|
193
vendor/golang.org/x/crypto/sha3/sha3.go
generated
vendored
Normal file
193
vendor/golang.org/x/crypto/sha3/sha3.go
generated
vendored
Normal file
@ -0,0 +1,193 @@
|
|||||||
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package sha3
|
||||||
|
|
||||||
|
// spongeDirection indicates the direction bytes are flowing through the sponge.
|
||||||
|
type spongeDirection int
|
||||||
|
|
||||||
|
const (
|
||||||
|
// spongeAbsorbing indicates that the sponge is absorbing input.
|
||||||
|
spongeAbsorbing spongeDirection = iota
|
||||||
|
// spongeSqueezing indicates that the sponge is being squeezed.
|
||||||
|
spongeSqueezing
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// maxRate is the maximum size of the internal buffer. SHAKE-256
|
||||||
|
// currently needs the largest buffer.
|
||||||
|
maxRate = 168
|
||||||
|
)
|
||||||
|
|
||||||
|
type state struct {
|
||||||
|
// Generic sponge components.
|
||||||
|
a [25]uint64 // main state of the hash
|
||||||
|
buf []byte // points into storage
|
||||||
|
rate int // the number of bytes of state to use
|
||||||
|
|
||||||
|
// dsbyte contains the "domain separation" bits and the first bit of
|
||||||
|
// the padding. Sections 6.1 and 6.2 of [1] separate the outputs of the
|
||||||
|
// SHA-3 and SHAKE functions by appending bitstrings to the message.
|
||||||
|
// Using a little-endian bit-ordering convention, these are "01" for SHA-3
|
||||||
|
// and "1111" for SHAKE, or 00000010b and 00001111b, respectively. Then the
|
||||||
|
// padding rule from section 5.1 is applied to pad the message to a multiple
|
||||||
|
// of the rate, which involves adding a "1" bit, zero or more "0" bits, and
|
||||||
|
// a final "1" bit. We merge the first "1" bit from the padding into dsbyte,
|
||||||
|
// giving 00000110b (0x06) and 00011111b (0x1f).
|
||||||
|
// [1] http://csrc.nist.gov/publications/drafts/fips-202/fips_202_draft.pdf
|
||||||
|
// "Draft FIPS 202: SHA-3 Standard: Permutation-Based Hash and
|
||||||
|
// Extendable-Output Functions (May 2014)"
|
||||||
|
dsbyte byte
|
||||||
|
|
||||||
|
storage storageBuf
|
||||||
|
|
||||||
|
// Specific to SHA-3 and SHAKE.
|
||||||
|
outputLen int // the default output size in bytes
|
||||||
|
state spongeDirection // whether the sponge is absorbing or squeezing
|
||||||
|
}
|
||||||
|
|
||||||
|
// BlockSize returns the rate of sponge underlying this hash function.
|
||||||
|
func (d *state) BlockSize() int { return d.rate }
|
||||||
|
|
||||||
|
// Size returns the output size of the hash function in bytes.
|
||||||
|
func (d *state) Size() int { return d.outputLen }
|
||||||
|
|
||||||
|
// Reset clears the internal state by zeroing the sponge state and
|
||||||
|
// the byte buffer, and setting Sponge.state to absorbing.
|
||||||
|
func (d *state) Reset() {
|
||||||
|
// Zero the permutation's state.
|
||||||
|
for i := range d.a {
|
||||||
|
d.a[i] = 0
|
||||||
|
}
|
||||||
|
d.state = spongeAbsorbing
|
||||||
|
d.buf = d.storage.asBytes()[:0]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *state) clone() *state {
|
||||||
|
ret := *d
|
||||||
|
if ret.state == spongeAbsorbing {
|
||||||
|
ret.buf = ret.storage.asBytes()[:len(ret.buf)]
|
||||||
|
} else {
|
||||||
|
ret.buf = ret.storage.asBytes()[d.rate-cap(d.buf) : d.rate]
|
||||||
|
}
|
||||||
|
|
||||||
|
return &ret
|
||||||
|
}
|
||||||
|
|
||||||
|
// permute applies the KeccakF-1600 permutation. It handles
|
||||||
|
// any input-output buffering.
|
||||||
|
func (d *state) permute() {
|
||||||
|
switch d.state {
|
||||||
|
case spongeAbsorbing:
|
||||||
|
// If we're absorbing, we need to xor the input into the state
|
||||||
|
// before applying the permutation.
|
||||||
|
xorIn(d, d.buf)
|
||||||
|
d.buf = d.storage.asBytes()[:0]
|
||||||
|
keccakF1600(&d.a)
|
||||||
|
case spongeSqueezing:
|
||||||
|
// If we're squeezing, we need to apply the permutatin before
|
||||||
|
// copying more output.
|
||||||
|
keccakF1600(&d.a)
|
||||||
|
d.buf = d.storage.asBytes()[:d.rate]
|
||||||
|
copyOut(d, d.buf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// pads appends the domain separation bits in dsbyte, applies
|
||||||
|
// the multi-bitrate 10..1 padding rule, and permutes the state.
|
||||||
|
func (d *state) padAndPermute(dsbyte byte) {
|
||||||
|
if d.buf == nil {
|
||||||
|
d.buf = d.storage.asBytes()[:0]
|
||||||
|
}
|
||||||
|
// Pad with this instance's domain-separator bits. We know that there's
|
||||||
|
// at least one byte of space in d.buf because, if it were full,
|
||||||
|
// permute would have been called to empty it. dsbyte also contains the
|
||||||
|
// first one bit for the padding. See the comment in the state struct.
|
||||||
|
d.buf = append(d.buf, dsbyte)
|
||||||
|
zerosStart := len(d.buf)
|
||||||
|
d.buf = d.storage.asBytes()[:d.rate]
|
||||||
|
for i := zerosStart; i < d.rate; i++ {
|
||||||
|
d.buf[i] = 0
|
||||||
|
}
|
||||||
|
// This adds the final one bit for the padding. Because of the way that
|
||||||
|
// bits are numbered from the LSB upwards, the final bit is the MSB of
|
||||||
|
// the last byte.
|
||||||
|
d.buf[d.rate-1] ^= 0x80
|
||||||
|
// Apply the permutation
|
||||||
|
d.permute()
|
||||||
|
d.state = spongeSqueezing
|
||||||
|
d.buf = d.storage.asBytes()[:d.rate]
|
||||||
|
copyOut(d, d.buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write absorbs more data into the hash's state. It produces an error
|
||||||
|
// if more data is written to the ShakeHash after writing
|
||||||
|
func (d *state) Write(p []byte) (written int, err error) {
|
||||||
|
if d.state != spongeAbsorbing {
|
||||||
|
panic("sha3: write to sponge after read")
|
||||||
|
}
|
||||||
|
if d.buf == nil {
|
||||||
|
d.buf = d.storage.asBytes()[:0]
|
||||||
|
}
|
||||||
|
written = len(p)
|
||||||
|
|
||||||
|
for len(p) > 0 {
|
||||||
|
if len(d.buf) == 0 && len(p) >= d.rate {
|
||||||
|
// The fast path; absorb a full "rate" bytes of input and apply the permutation.
|
||||||
|
xorIn(d, p[:d.rate])
|
||||||
|
p = p[d.rate:]
|
||||||
|
keccakF1600(&d.a)
|
||||||
|
} else {
|
||||||
|
// The slow path; buffer the input until we can fill the sponge, and then xor it in.
|
||||||
|
todo := d.rate - len(d.buf)
|
||||||
|
if todo > len(p) {
|
||||||
|
todo = len(p)
|
||||||
|
}
|
||||||
|
d.buf = append(d.buf, p[:todo]...)
|
||||||
|
p = p[todo:]
|
||||||
|
|
||||||
|
// If the sponge is full, apply the permutation.
|
||||||
|
if len(d.buf) == d.rate {
|
||||||
|
d.permute()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read squeezes an arbitrary number of bytes from the sponge.
|
||||||
|
func (d *state) Read(out []byte) (n int, err error) {
|
||||||
|
// If we're still absorbing, pad and apply the permutation.
|
||||||
|
if d.state == spongeAbsorbing {
|
||||||
|
d.padAndPermute(d.dsbyte)
|
||||||
|
}
|
||||||
|
|
||||||
|
n = len(out)
|
||||||
|
|
||||||
|
// Now, do the squeezing.
|
||||||
|
for len(out) > 0 {
|
||||||
|
n := copy(out, d.buf)
|
||||||
|
d.buf = d.buf[n:]
|
||||||
|
out = out[n:]
|
||||||
|
|
||||||
|
// Apply the permutation if we've squeezed the sponge dry.
|
||||||
|
if len(d.buf) == 0 {
|
||||||
|
d.permute()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sum applies padding to the hash state and then squeezes out the desired
|
||||||
|
// number of output bytes.
|
||||||
|
func (d *state) Sum(in []byte) []byte {
|
||||||
|
// Make a copy of the original hash so that caller can keep writing
|
||||||
|
// and summing.
|
||||||
|
dup := d.clone()
|
||||||
|
hash := make([]byte, dup.outputLen)
|
||||||
|
dup.Read(hash)
|
||||||
|
return append(in, hash...)
|
||||||
|
}
|
284
vendor/golang.org/x/crypto/sha3/sha3_s390x.go
generated
vendored
Normal file
284
vendor/golang.org/x/crypto/sha3/sha3_s390x.go
generated
vendored
Normal file
@ -0,0 +1,284 @@
|
|||||||
|
// Copyright 2017 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !gccgo,!appengine
|
||||||
|
|
||||||
|
package sha3
|
||||||
|
|
||||||
|
// This file contains code for using the 'compute intermediate
|
||||||
|
// message digest' (KIMD) and 'compute last message digest' (KLMD)
|
||||||
|
// instructions to compute SHA-3 and SHAKE hashes on IBM Z.
|
||||||
|
|
||||||
|
import (
|
||||||
|
"hash"
|
||||||
|
|
||||||
|
"golang.org/x/sys/cpu"
|
||||||
|
)
|
||||||
|
|
||||||
|
// codes represent 7-bit KIMD/KLMD function codes as defined in
|
||||||
|
// the Principles of Operation.
|
||||||
|
type code uint64
|
||||||
|
|
||||||
|
const (
|
||||||
|
// function codes for KIMD/KLMD
|
||||||
|
sha3_224 code = 32
|
||||||
|
sha3_256 = 33
|
||||||
|
sha3_384 = 34
|
||||||
|
sha3_512 = 35
|
||||||
|
shake_128 = 36
|
||||||
|
shake_256 = 37
|
||||||
|
nopad = 0x100
|
||||||
|
)
|
||||||
|
|
||||||
|
// kimd is a wrapper for the 'compute intermediate message digest' instruction.
|
||||||
|
// src must be a multiple of the rate for the given function code.
|
||||||
|
//go:noescape
|
||||||
|
func kimd(function code, chain *[200]byte, src []byte)
|
||||||
|
|
||||||
|
// klmd is a wrapper for the 'compute last message digest' instruction.
|
||||||
|
// src padding is handled by the instruction.
|
||||||
|
//go:noescape
|
||||||
|
func klmd(function code, chain *[200]byte, dst, src []byte)
|
||||||
|
|
||||||
|
type asmState struct {
|
||||||
|
a [200]byte // 1600 bit state
|
||||||
|
buf []byte // care must be taken to ensure cap(buf) is a multiple of rate
|
||||||
|
rate int // equivalent to block size
|
||||||
|
storage [3072]byte // underlying storage for buf
|
||||||
|
outputLen int // output length if fixed, 0 if not
|
||||||
|
function code // KIMD/KLMD function code
|
||||||
|
state spongeDirection // whether the sponge is absorbing or squeezing
|
||||||
|
}
|
||||||
|
|
||||||
|
func newAsmState(function code) *asmState {
|
||||||
|
var s asmState
|
||||||
|
s.function = function
|
||||||
|
switch function {
|
||||||
|
case sha3_224:
|
||||||
|
s.rate = 144
|
||||||
|
s.outputLen = 28
|
||||||
|
case sha3_256:
|
||||||
|
s.rate = 136
|
||||||
|
s.outputLen = 32
|
||||||
|
case sha3_384:
|
||||||
|
s.rate = 104
|
||||||
|
s.outputLen = 48
|
||||||
|
case sha3_512:
|
||||||
|
s.rate = 72
|
||||||
|
s.outputLen = 64
|
||||||
|
case shake_128:
|
||||||
|
s.rate = 168
|
||||||
|
case shake_256:
|
||||||
|
s.rate = 136
|
||||||
|
default:
|
||||||
|
panic("sha3: unrecognized function code")
|
||||||
|
}
|
||||||
|
|
||||||
|
// limit s.buf size to a multiple of s.rate
|
||||||
|
s.resetBuf()
|
||||||
|
return &s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *asmState) clone() *asmState {
|
||||||
|
c := *s
|
||||||
|
c.buf = c.storage[:len(s.buf):cap(s.buf)]
|
||||||
|
return &c
|
||||||
|
}
|
||||||
|
|
||||||
|
// copyIntoBuf copies b into buf. It will panic if there is not enough space to
|
||||||
|
// store all of b.
|
||||||
|
func (s *asmState) copyIntoBuf(b []byte) {
|
||||||
|
bufLen := len(s.buf)
|
||||||
|
s.buf = s.buf[:len(s.buf)+len(b)]
|
||||||
|
copy(s.buf[bufLen:], b)
|
||||||
|
}
|
||||||
|
|
||||||
|
// resetBuf points buf at storage, sets the length to 0 and sets cap to be a
|
||||||
|
// multiple of the rate.
|
||||||
|
func (s *asmState) resetBuf() {
|
||||||
|
max := (cap(s.storage) / s.rate) * s.rate
|
||||||
|
s.buf = s.storage[:0:max]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write (via the embedded io.Writer interface) adds more data to the running hash.
|
||||||
|
// It never returns an error.
|
||||||
|
func (s *asmState) Write(b []byte) (int, error) {
|
||||||
|
if s.state != spongeAbsorbing {
|
||||||
|
panic("sha3: write to sponge after read")
|
||||||
|
}
|
||||||
|
length := len(b)
|
||||||
|
for len(b) > 0 {
|
||||||
|
if len(s.buf) == 0 && len(b) >= cap(s.buf) {
|
||||||
|
// Hash the data directly and push any remaining bytes
|
||||||
|
// into the buffer.
|
||||||
|
remainder := len(b) % s.rate
|
||||||
|
kimd(s.function, &s.a, b[:len(b)-remainder])
|
||||||
|
if remainder != 0 {
|
||||||
|
s.copyIntoBuf(b[len(b)-remainder:])
|
||||||
|
}
|
||||||
|
return length, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(s.buf) == cap(s.buf) {
|
||||||
|
// flush the buffer
|
||||||
|
kimd(s.function, &s.a, s.buf)
|
||||||
|
s.buf = s.buf[:0]
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy as much as we can into the buffer
|
||||||
|
n := len(b)
|
||||||
|
if len(b) > cap(s.buf)-len(s.buf) {
|
||||||
|
n = cap(s.buf) - len(s.buf)
|
||||||
|
}
|
||||||
|
s.copyIntoBuf(b[:n])
|
||||||
|
b = b[n:]
|
||||||
|
}
|
||||||
|
return length, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read squeezes an arbitrary number of bytes from the sponge.
|
||||||
|
func (s *asmState) Read(out []byte) (n int, err error) {
|
||||||
|
n = len(out)
|
||||||
|
|
||||||
|
// need to pad if we were absorbing
|
||||||
|
if s.state == spongeAbsorbing {
|
||||||
|
s.state = spongeSqueezing
|
||||||
|
|
||||||
|
// write hash directly into out if possible
|
||||||
|
if len(out)%s.rate == 0 {
|
||||||
|
klmd(s.function, &s.a, out, s.buf) // len(out) may be 0
|
||||||
|
s.buf = s.buf[:0]
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// write hash into buffer
|
||||||
|
max := cap(s.buf)
|
||||||
|
if max > len(out) {
|
||||||
|
max = (len(out)/s.rate)*s.rate + s.rate
|
||||||
|
}
|
||||||
|
klmd(s.function, &s.a, s.buf[:max], s.buf)
|
||||||
|
s.buf = s.buf[:max]
|
||||||
|
}
|
||||||
|
|
||||||
|
for len(out) > 0 {
|
||||||
|
// flush the buffer
|
||||||
|
if len(s.buf) != 0 {
|
||||||
|
c := copy(out, s.buf)
|
||||||
|
out = out[c:]
|
||||||
|
s.buf = s.buf[c:]
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// write hash directly into out if possible
|
||||||
|
if len(out)%s.rate == 0 {
|
||||||
|
klmd(s.function|nopad, &s.a, out, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// write hash into buffer
|
||||||
|
s.resetBuf()
|
||||||
|
if cap(s.buf) > len(out) {
|
||||||
|
s.buf = s.buf[:(len(out)/s.rate)*s.rate+s.rate]
|
||||||
|
}
|
||||||
|
klmd(s.function|nopad, &s.a, s.buf, nil)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sum appends the current hash to b and returns the resulting slice.
|
||||||
|
// It does not change the underlying hash state.
|
||||||
|
func (s *asmState) Sum(b []byte) []byte {
|
||||||
|
if s.outputLen == 0 {
|
||||||
|
panic("sha3: cannot call Sum on SHAKE functions")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy the state to preserve the original.
|
||||||
|
a := s.a
|
||||||
|
|
||||||
|
// Hash the buffer. Note that we don't clear it because we
|
||||||
|
// aren't updating the state.
|
||||||
|
klmd(s.function, &a, nil, s.buf)
|
||||||
|
return append(b, a[:s.outputLen]...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset resets the Hash to its initial state.
|
||||||
|
func (s *asmState) Reset() {
|
||||||
|
for i := range s.a {
|
||||||
|
s.a[i] = 0
|
||||||
|
}
|
||||||
|
s.resetBuf()
|
||||||
|
s.state = spongeAbsorbing
|
||||||
|
}
|
||||||
|
|
||||||
|
// Size returns the number of bytes Sum will return.
|
||||||
|
func (s *asmState) Size() int {
|
||||||
|
return s.outputLen
|
||||||
|
}
|
||||||
|
|
||||||
|
// BlockSize returns the hash's underlying block size.
|
||||||
|
// The Write method must be able to accept any amount
|
||||||
|
// of data, but it may operate more efficiently if all writes
|
||||||
|
// are a multiple of the block size.
|
||||||
|
func (s *asmState) BlockSize() int {
|
||||||
|
return s.rate
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clone returns a copy of the ShakeHash in its current state.
|
||||||
|
func (s *asmState) Clone() ShakeHash {
|
||||||
|
return s.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
// new224Asm returns an assembly implementation of SHA3-224 if available,
|
||||||
|
// otherwise it returns nil.
|
||||||
|
func new224Asm() hash.Hash {
|
||||||
|
if cpu.S390X.HasSHA3 {
|
||||||
|
return newAsmState(sha3_224)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// new256Asm returns an assembly implementation of SHA3-256 if available,
|
||||||
|
// otherwise it returns nil.
|
||||||
|
func new256Asm() hash.Hash {
|
||||||
|
if cpu.S390X.HasSHA3 {
|
||||||
|
return newAsmState(sha3_256)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// new384Asm returns an assembly implementation of SHA3-384 if available,
|
||||||
|
// otherwise it returns nil.
|
||||||
|
func new384Asm() hash.Hash {
|
||||||
|
if cpu.S390X.HasSHA3 {
|
||||||
|
return newAsmState(sha3_384)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// new512Asm returns an assembly implementation of SHA3-512 if available,
|
||||||
|
// otherwise it returns nil.
|
||||||
|
func new512Asm() hash.Hash {
|
||||||
|
if cpu.S390X.HasSHA3 {
|
||||||
|
return newAsmState(sha3_512)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// newShake128Asm returns an assembly implementation of SHAKE-128 if available,
|
||||||
|
// otherwise it returns nil.
|
||||||
|
func newShake128Asm() ShakeHash {
|
||||||
|
if cpu.S390X.HasSHA3 {
|
||||||
|
return newAsmState(shake_128)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// newShake256Asm returns an assembly implementation of SHAKE-256 if available,
|
||||||
|
// otherwise it returns nil.
|
||||||
|
func newShake256Asm() ShakeHash {
|
||||||
|
if cpu.S390X.HasSHA3 {
|
||||||
|
return newAsmState(shake_256)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
33
vendor/golang.org/x/crypto/sha3/sha3_s390x.s
generated
vendored
Normal file
33
vendor/golang.org/x/crypto/sha3/sha3_s390x.s
generated
vendored
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
// Copyright 2017 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !gccgo,!appengine
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
// func kimd(function code, chain *[200]byte, src []byte)
|
||||||
|
TEXT ·kimd(SB), NOFRAME|NOSPLIT, $0-40
|
||||||
|
MOVD function+0(FP), R0
|
||||||
|
MOVD chain+8(FP), R1
|
||||||
|
LMG src+16(FP), R2, R3 // R2=base, R3=len
|
||||||
|
|
||||||
|
continue:
|
||||||
|
WORD $0xB93E0002 // KIMD --, R2
|
||||||
|
BVS continue // continue if interrupted
|
||||||
|
MOVD $0, R0 // reset R0 for pre-go1.8 compilers
|
||||||
|
RET
|
||||||
|
|
||||||
|
// func klmd(function code, chain *[200]byte, dst, src []byte)
|
||||||
|
TEXT ·klmd(SB), NOFRAME|NOSPLIT, $0-64
|
||||||
|
// TODO: SHAKE support
|
||||||
|
MOVD function+0(FP), R0
|
||||||
|
MOVD chain+8(FP), R1
|
||||||
|
LMG dst+16(FP), R2, R3 // R2=base, R3=len
|
||||||
|
LMG src+40(FP), R4, R5 // R4=base, R5=len
|
||||||
|
|
||||||
|
continue:
|
||||||
|
WORD $0xB93F0024 // KLMD R2, R4
|
||||||
|
BVS continue // continue if interrupted
|
||||||
|
MOVD $0, R0 // reset R0 for pre-go1.8 compilers
|
||||||
|
RET
|
173
vendor/golang.org/x/crypto/sha3/shake.go
generated
vendored
Normal file
173
vendor/golang.org/x/crypto/sha3/shake.go
generated
vendored
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package sha3
|
||||||
|
|
||||||
|
// This file defines the ShakeHash interface, and provides
|
||||||
|
// functions for creating SHAKE and cSHAKE instances, as well as utility
|
||||||
|
// functions for hashing bytes to arbitrary-length output.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// SHAKE implementation is based on FIPS PUB 202 [1]
|
||||||
|
// cSHAKE implementations is based on NIST SP 800-185 [2]
|
||||||
|
//
|
||||||
|
// [1] https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf
|
||||||
|
// [2] https://doi.org/10.6028/NIST.SP.800-185
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ShakeHash defines the interface to hash functions that
|
||||||
|
// support arbitrary-length output.
|
||||||
|
type ShakeHash interface {
|
||||||
|
// Write absorbs more data into the hash's state. It panics if input is
|
||||||
|
// written to it after output has been read from it.
|
||||||
|
io.Writer
|
||||||
|
|
||||||
|
// Read reads more output from the hash; reading affects the hash's
|
||||||
|
// state. (ShakeHash.Read is thus very different from Hash.Sum)
|
||||||
|
// It never returns an error.
|
||||||
|
io.Reader
|
||||||
|
|
||||||
|
// Clone returns a copy of the ShakeHash in its current state.
|
||||||
|
Clone() ShakeHash
|
||||||
|
|
||||||
|
// Reset resets the ShakeHash to its initial state.
|
||||||
|
Reset()
|
||||||
|
}
|
||||||
|
|
||||||
|
// cSHAKE specific context
|
||||||
|
type cshakeState struct {
|
||||||
|
*state // SHA-3 state context and Read/Write operations
|
||||||
|
|
||||||
|
// initBlock is the cSHAKE specific initialization set of bytes. It is initialized
|
||||||
|
// by newCShake function and stores concatenation of N followed by S, encoded
|
||||||
|
// by the method specified in 3.3 of [1].
|
||||||
|
// It is stored here in order for Reset() to be able to put context into
|
||||||
|
// initial state.
|
||||||
|
initBlock []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// Consts for configuring initial SHA-3 state
|
||||||
|
const (
|
||||||
|
dsbyteShake = 0x1f
|
||||||
|
dsbyteCShake = 0x04
|
||||||
|
rate128 = 168
|
||||||
|
rate256 = 136
|
||||||
|
)
|
||||||
|
|
||||||
|
func bytepad(input []byte, w int) []byte {
|
||||||
|
// leftEncode always returns max 9 bytes
|
||||||
|
buf := make([]byte, 0, 9+len(input)+w)
|
||||||
|
buf = append(buf, leftEncode(uint64(w))...)
|
||||||
|
buf = append(buf, input...)
|
||||||
|
padlen := w - (len(buf) % w)
|
||||||
|
return append(buf, make([]byte, padlen)...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func leftEncode(value uint64) []byte {
|
||||||
|
var b [9]byte
|
||||||
|
binary.BigEndian.PutUint64(b[1:], value)
|
||||||
|
// Trim all but last leading zero bytes
|
||||||
|
i := byte(1)
|
||||||
|
for i < 8 && b[i] == 0 {
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
// Prepend number of encoded bytes
|
||||||
|
b[i-1] = 9 - i
|
||||||
|
return b[i-1:]
|
||||||
|
}
|
||||||
|
|
||||||
|
func newCShake(N, S []byte, rate int, dsbyte byte) ShakeHash {
|
||||||
|
c := cshakeState{state: &state{rate: rate, dsbyte: dsbyte}}
|
||||||
|
|
||||||
|
// leftEncode returns max 9 bytes
|
||||||
|
c.initBlock = make([]byte, 0, 9*2+len(N)+len(S))
|
||||||
|
c.initBlock = append(c.initBlock, leftEncode(uint64(len(N)*8))...)
|
||||||
|
c.initBlock = append(c.initBlock, N...)
|
||||||
|
c.initBlock = append(c.initBlock, leftEncode(uint64(len(S)*8))...)
|
||||||
|
c.initBlock = append(c.initBlock, S...)
|
||||||
|
c.Write(bytepad(c.initBlock, c.rate))
|
||||||
|
return &c
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset resets the hash to initial state.
|
||||||
|
func (c *cshakeState) Reset() {
|
||||||
|
c.state.Reset()
|
||||||
|
c.Write(bytepad(c.initBlock, c.rate))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clone returns copy of a cSHAKE context within its current state.
|
||||||
|
func (c *cshakeState) Clone() ShakeHash {
|
||||||
|
b := make([]byte, len(c.initBlock))
|
||||||
|
copy(b, c.initBlock)
|
||||||
|
return &cshakeState{state: c.clone(), initBlock: b}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clone returns copy of SHAKE context within its current state.
|
||||||
|
func (c *state) Clone() ShakeHash {
|
||||||
|
return c.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewShake128 creates a new SHAKE128 variable-output-length ShakeHash.
|
||||||
|
// Its generic security strength is 128 bits against all attacks if at
|
||||||
|
// least 32 bytes of its output are used.
|
||||||
|
func NewShake128() ShakeHash {
|
||||||
|
if h := newShake128Asm(); h != nil {
|
||||||
|
return h
|
||||||
|
}
|
||||||
|
return &state{rate: rate128, dsbyte: dsbyteShake}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewShake256 creates a new SHAKE256 variable-output-length ShakeHash.
|
||||||
|
// Its generic security strength is 256 bits against all attacks if
|
||||||
|
// at least 64 bytes of its output are used.
|
||||||
|
func NewShake256() ShakeHash {
|
||||||
|
if h := newShake256Asm(); h != nil {
|
||||||
|
return h
|
||||||
|
}
|
||||||
|
return &state{rate: rate256, dsbyte: dsbyteShake}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewCShake128 creates a new instance of cSHAKE128 variable-output-length ShakeHash,
|
||||||
|
// a customizable variant of SHAKE128.
|
||||||
|
// N is used to define functions based on cSHAKE, it can be empty when plain cSHAKE is
|
||||||
|
// desired. S is a customization byte string used for domain separation - two cSHAKE
|
||||||
|
// computations on same input with different S yield unrelated outputs.
|
||||||
|
// When N and S are both empty, this is equivalent to NewShake128.
|
||||||
|
func NewCShake128(N, S []byte) ShakeHash {
|
||||||
|
if len(N) == 0 && len(S) == 0 {
|
||||||
|
return NewShake128()
|
||||||
|
}
|
||||||
|
return newCShake(N, S, rate128, dsbyteCShake)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewCShake256 creates a new instance of cSHAKE256 variable-output-length ShakeHash,
|
||||||
|
// a customizable variant of SHAKE256.
|
||||||
|
// N is used to define functions based on cSHAKE, it can be empty when plain cSHAKE is
|
||||||
|
// desired. S is a customization byte string used for domain separation - two cSHAKE
|
||||||
|
// computations on same input with different S yield unrelated outputs.
|
||||||
|
// When N and S are both empty, this is equivalent to NewShake256.
|
||||||
|
func NewCShake256(N, S []byte) ShakeHash {
|
||||||
|
if len(N) == 0 && len(S) == 0 {
|
||||||
|
return NewShake256()
|
||||||
|
}
|
||||||
|
return newCShake(N, S, rate256, dsbyteCShake)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ShakeSum128 writes an arbitrary-length digest of data into hash.
|
||||||
|
func ShakeSum128(hash, data []byte) {
|
||||||
|
h := NewShake128()
|
||||||
|
h.Write(data)
|
||||||
|
h.Read(hash)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ShakeSum256 writes an arbitrary-length digest of data into hash.
|
||||||
|
func ShakeSum256(hash, data []byte) {
|
||||||
|
h := NewShake256()
|
||||||
|
h.Write(data)
|
||||||
|
h.Read(hash)
|
||||||
|
}
|
19
vendor/golang.org/x/crypto/sha3/shake_generic.go
generated
vendored
Normal file
19
vendor/golang.org/x/crypto/sha3/shake_generic.go
generated
vendored
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
// Copyright 2017 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build gccgo appengine !s390x
|
||||||
|
|
||||||
|
package sha3
|
||||||
|
|
||||||
|
// newShake128Asm returns an assembly implementation of SHAKE-128 if available,
|
||||||
|
// otherwise it returns nil.
|
||||||
|
func newShake128Asm() ShakeHash {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// newShake256Asm returns an assembly implementation of SHAKE-256 if available,
|
||||||
|
// otherwise it returns nil.
|
||||||
|
func newShake256Asm() ShakeHash {
|
||||||
|
return nil
|
||||||
|
}
|
23
vendor/golang.org/x/crypto/sha3/xor.go
generated
vendored
Normal file
23
vendor/golang.org/x/crypto/sha3/xor.go
generated
vendored
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
// Copyright 2015 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !amd64,!386,!ppc64le appengine
|
||||||
|
|
||||||
|
package sha3
|
||||||
|
|
||||||
|
// A storageBuf is an aligned array of maxRate bytes.
|
||||||
|
type storageBuf [maxRate]byte
|
||||||
|
|
||||||
|
func (b *storageBuf) asBytes() *[maxRate]byte {
|
||||||
|
return (*[maxRate]byte)(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
xorIn = xorInGeneric
|
||||||
|
copyOut = copyOutGeneric
|
||||||
|
xorInUnaligned = xorInGeneric
|
||||||
|
copyOutUnaligned = copyOutGeneric
|
||||||
|
)
|
||||||
|
|
||||||
|
const xorImplementationUnaligned = "generic"
|
28
vendor/golang.org/x/crypto/sha3/xor_generic.go
generated
vendored
Normal file
28
vendor/golang.org/x/crypto/sha3/xor_generic.go
generated
vendored
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
// Copyright 2015 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package sha3
|
||||||
|
|
||||||
|
import "encoding/binary"
|
||||||
|
|
||||||
|
// xorInGeneric xors the bytes in buf into the state; it
|
||||||
|
// makes no non-portable assumptions about memory layout
|
||||||
|
// or alignment.
|
||||||
|
func xorInGeneric(d *state, buf []byte) {
|
||||||
|
n := len(buf) / 8
|
||||||
|
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
a := binary.LittleEndian.Uint64(buf)
|
||||||
|
d.a[i] ^= a
|
||||||
|
buf = buf[8:]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// copyOutGeneric copies ulint64s to a byte buffer.
|
||||||
|
func copyOutGeneric(d *state, b []byte) {
|
||||||
|
for i := 0; len(b) >= 8; i++ {
|
||||||
|
binary.LittleEndian.PutUint64(b, d.a[i])
|
||||||
|
b = b[8:]
|
||||||
|
}
|
||||||
|
}
|
67
vendor/golang.org/x/crypto/sha3/xor_unaligned.go
generated
vendored
Normal file
67
vendor/golang.org/x/crypto/sha3/xor_unaligned.go
generated
vendored
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
// Copyright 2015 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build amd64 386 ppc64le
|
||||||
|
// +build !appengine
|
||||||
|
|
||||||
|
package sha3
|
||||||
|
|
||||||
|
import "unsafe"
|
||||||
|
|
||||||
|
// A storageBuf is an aligned array of maxRate bytes.
|
||||||
|
type storageBuf [maxRate / 8]uint64
|
||||||
|
|
||||||
|
func (b *storageBuf) asBytes() *[maxRate]byte {
|
||||||
|
return (*[maxRate]byte)(unsafe.Pointer(b))
|
||||||
|
}
|
||||||
|
|
||||||
|
// xorInUnaligned uses unaligned reads and writes to update d.a to contain d.a
|
||||||
|
// XOR buf.
|
||||||
|
func xorInUnaligned(d *state, buf []byte) {
|
||||||
|
n := len(buf)
|
||||||
|
bw := (*[maxRate / 8]uint64)(unsafe.Pointer(&buf[0]))[: n/8 : n/8]
|
||||||
|
if n >= 72 {
|
||||||
|
d.a[0] ^= bw[0]
|
||||||
|
d.a[1] ^= bw[1]
|
||||||
|
d.a[2] ^= bw[2]
|
||||||
|
d.a[3] ^= bw[3]
|
||||||
|
d.a[4] ^= bw[4]
|
||||||
|
d.a[5] ^= bw[5]
|
||||||
|
d.a[6] ^= bw[6]
|
||||||
|
d.a[7] ^= bw[7]
|
||||||
|
d.a[8] ^= bw[8]
|
||||||
|
}
|
||||||
|
if n >= 104 {
|
||||||
|
d.a[9] ^= bw[9]
|
||||||
|
d.a[10] ^= bw[10]
|
||||||
|
d.a[11] ^= bw[11]
|
||||||
|
d.a[12] ^= bw[12]
|
||||||
|
}
|
||||||
|
if n >= 136 {
|
||||||
|
d.a[13] ^= bw[13]
|
||||||
|
d.a[14] ^= bw[14]
|
||||||
|
d.a[15] ^= bw[15]
|
||||||
|
d.a[16] ^= bw[16]
|
||||||
|
}
|
||||||
|
if n >= 144 {
|
||||||
|
d.a[17] ^= bw[17]
|
||||||
|
}
|
||||||
|
if n >= 168 {
|
||||||
|
d.a[18] ^= bw[18]
|
||||||
|
d.a[19] ^= bw[19]
|
||||||
|
d.a[20] ^= bw[20]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func copyOutUnaligned(d *state, buf []byte) {
|
||||||
|
ab := (*[maxRate]uint8)(unsafe.Pointer(&d.a[0]))
|
||||||
|
copy(buf, ab[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
xorIn = xorInUnaligned
|
||||||
|
copyOut = copyOutUnaligned
|
||||||
|
)
|
||||||
|
|
||||||
|
const xorImplementationUnaligned = "unaligned"
|
3
vendor/golang.org/x/net/AUTHORS
generated
vendored
Normal file
3
vendor/golang.org/x/net/AUTHORS
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# This source code refers to The Go Authors for copyright purposes.
|
||||||
|
# The master list of authors is in the main Go distribution,
|
||||||
|
# visible at http://tip.golang.org/AUTHORS.
|
3
vendor/golang.org/x/net/CONTRIBUTORS
generated
vendored
Normal file
3
vendor/golang.org/x/net/CONTRIBUTORS
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# This source code was written by the Go contributors.
|
||||||
|
# The master list of contributors is in the main Go distribution,
|
||||||
|
# visible at http://tip.golang.org/CONTRIBUTORS.
|
27
vendor/golang.org/x/net/LICENSE
generated
vendored
Normal file
27
vendor/golang.org/x/net/LICENSE
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
Copyright (c) 2009 The Go Authors. All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* 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.
|
||||||
|
* Neither the name of Google Inc. nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
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
|
||||||
|
OWNER 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.
|
22
vendor/golang.org/x/net/PATENTS
generated
vendored
Normal file
22
vendor/golang.org/x/net/PATENTS
generated
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
Additional IP Rights Grant (Patents)
|
||||||
|
|
||||||
|
"This implementation" means the copyrightable works distributed by
|
||||||
|
Google as part of the Go project.
|
||||||
|
|
||||||
|
Google hereby grants to You a perpetual, worldwide, non-exclusive,
|
||||||
|
no-charge, royalty-free, irrevocable (except as stated in this section)
|
||||||
|
patent license to make, have made, use, offer to sell, sell, import,
|
||||||
|
transfer and otherwise run, modify and propagate the contents of this
|
||||||
|
implementation of Go, where such license applies only to those patent
|
||||||
|
claims, both currently owned or controlled by Google and acquired in
|
||||||
|
the future, licensable by Google that are necessarily infringed by this
|
||||||
|
implementation of Go. This grant does not include claims that would be
|
||||||
|
infringed only as a consequence of further modification of this
|
||||||
|
implementation. If you or your agent or exclusive licensee institute or
|
||||||
|
order or agree to the institution of patent litigation against any
|
||||||
|
entity (including a cross-claim or counterclaim in a lawsuit) alleging
|
||||||
|
that this implementation of Go or any code incorporated within this
|
||||||
|
implementation of Go constitutes direct or contributory patent
|
||||||
|
infringement, or inducement of patent infringement, then any patent
|
||||||
|
rights granted to you under this License for this implementation of Go
|
||||||
|
shall terminate as of the date such litigation is filed.
|
168
vendor/golang.org/x/net/internal/socks/client.go
generated
vendored
Normal file
168
vendor/golang.org/x/net/internal/socks/client.go
generated
vendored
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package socks
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"io"
|
||||||
|
"net"
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
noDeadline = time.Time{}
|
||||||
|
aLongTimeAgo = time.Unix(1, 0)
|
||||||
|
)
|
||||||
|
|
||||||
|
func (d *Dialer) connect(ctx context.Context, c net.Conn, address string) (_ net.Addr, ctxErr error) {
|
||||||
|
host, port, err := splitHostPort(address)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if deadline, ok := ctx.Deadline(); ok && !deadline.IsZero() {
|
||||||
|
c.SetDeadline(deadline)
|
||||||
|
defer c.SetDeadline(noDeadline)
|
||||||
|
}
|
||||||
|
if ctx != context.Background() {
|
||||||
|
errCh := make(chan error, 1)
|
||||||
|
done := make(chan struct{})
|
||||||
|
defer func() {
|
||||||
|
close(done)
|
||||||
|
if ctxErr == nil {
|
||||||
|
ctxErr = <-errCh
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
go func() {
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
c.SetDeadline(aLongTimeAgo)
|
||||||
|
errCh <- ctx.Err()
|
||||||
|
case <-done:
|
||||||
|
errCh <- nil
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
b := make([]byte, 0, 6+len(host)) // the size here is just an estimate
|
||||||
|
b = append(b, Version5)
|
||||||
|
if len(d.AuthMethods) == 0 || d.Authenticate == nil {
|
||||||
|
b = append(b, 1, byte(AuthMethodNotRequired))
|
||||||
|
} else {
|
||||||
|
ams := d.AuthMethods
|
||||||
|
if len(ams) > 255 {
|
||||||
|
return nil, errors.New("too many authentication methods")
|
||||||
|
}
|
||||||
|
b = append(b, byte(len(ams)))
|
||||||
|
for _, am := range ams {
|
||||||
|
b = append(b, byte(am))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if _, ctxErr = c.Write(b); ctxErr != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ctxErr = io.ReadFull(c, b[:2]); ctxErr != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if b[0] != Version5 {
|
||||||
|
return nil, errors.New("unexpected protocol version " + strconv.Itoa(int(b[0])))
|
||||||
|
}
|
||||||
|
am := AuthMethod(b[1])
|
||||||
|
if am == AuthMethodNoAcceptableMethods {
|
||||||
|
return nil, errors.New("no acceptable authentication methods")
|
||||||
|
}
|
||||||
|
if d.Authenticate != nil {
|
||||||
|
if ctxErr = d.Authenticate(ctx, c, am); ctxErr != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
b = b[:0]
|
||||||
|
b = append(b, Version5, byte(d.cmd), 0)
|
||||||
|
if ip := net.ParseIP(host); ip != nil {
|
||||||
|
if ip4 := ip.To4(); ip4 != nil {
|
||||||
|
b = append(b, AddrTypeIPv4)
|
||||||
|
b = append(b, ip4...)
|
||||||
|
} else if ip6 := ip.To16(); ip6 != nil {
|
||||||
|
b = append(b, AddrTypeIPv6)
|
||||||
|
b = append(b, ip6...)
|
||||||
|
} else {
|
||||||
|
return nil, errors.New("unknown address type")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if len(host) > 255 {
|
||||||
|
return nil, errors.New("FQDN too long")
|
||||||
|
}
|
||||||
|
b = append(b, AddrTypeFQDN)
|
||||||
|
b = append(b, byte(len(host)))
|
||||||
|
b = append(b, host...)
|
||||||
|
}
|
||||||
|
b = append(b, byte(port>>8), byte(port))
|
||||||
|
if _, ctxErr = c.Write(b); ctxErr != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ctxErr = io.ReadFull(c, b[:4]); ctxErr != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if b[0] != Version5 {
|
||||||
|
return nil, errors.New("unexpected protocol version " + strconv.Itoa(int(b[0])))
|
||||||
|
}
|
||||||
|
if cmdErr := Reply(b[1]); cmdErr != StatusSucceeded {
|
||||||
|
return nil, errors.New("unknown error " + cmdErr.String())
|
||||||
|
}
|
||||||
|
if b[2] != 0 {
|
||||||
|
return nil, errors.New("non-zero reserved field")
|
||||||
|
}
|
||||||
|
l := 2
|
||||||
|
var a Addr
|
||||||
|
switch b[3] {
|
||||||
|
case AddrTypeIPv4:
|
||||||
|
l += net.IPv4len
|
||||||
|
a.IP = make(net.IP, net.IPv4len)
|
||||||
|
case AddrTypeIPv6:
|
||||||
|
l += net.IPv6len
|
||||||
|
a.IP = make(net.IP, net.IPv6len)
|
||||||
|
case AddrTypeFQDN:
|
||||||
|
if _, err := io.ReadFull(c, b[:1]); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
l += int(b[0])
|
||||||
|
default:
|
||||||
|
return nil, errors.New("unknown address type " + strconv.Itoa(int(b[3])))
|
||||||
|
}
|
||||||
|
if cap(b) < l {
|
||||||
|
b = make([]byte, l)
|
||||||
|
} else {
|
||||||
|
b = b[:l]
|
||||||
|
}
|
||||||
|
if _, ctxErr = io.ReadFull(c, b); ctxErr != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if a.IP != nil {
|
||||||
|
copy(a.IP, b)
|
||||||
|
} else {
|
||||||
|
a.Name = string(b[:len(b)-2])
|
||||||
|
}
|
||||||
|
a.Port = int(b[len(b)-2])<<8 | int(b[len(b)-1])
|
||||||
|
return &a, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func splitHostPort(address string) (string, int, error) {
|
||||||
|
host, port, err := net.SplitHostPort(address)
|
||||||
|
if err != nil {
|
||||||
|
return "", 0, err
|
||||||
|
}
|
||||||
|
portnum, err := strconv.Atoi(port)
|
||||||
|
if err != nil {
|
||||||
|
return "", 0, err
|
||||||
|
}
|
||||||
|
if 1 > portnum || portnum > 0xffff {
|
||||||
|
return "", 0, errors.New("port number out of range " + port)
|
||||||
|
}
|
||||||
|
return host, portnum, nil
|
||||||
|
}
|
317
vendor/golang.org/x/net/internal/socks/socks.go
generated
vendored
Normal file
317
vendor/golang.org/x/net/internal/socks/socks.go
generated
vendored
Normal file
@ -0,0 +1,317 @@
|
|||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Package socks provides a SOCKS version 5 client implementation.
|
||||||
|
//
|
||||||
|
// SOCKS protocol version 5 is defined in RFC 1928.
|
||||||
|
// Username/Password authentication for SOCKS version 5 is defined in
|
||||||
|
// RFC 1929.
|
||||||
|
package socks
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"io"
|
||||||
|
"net"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A Command represents a SOCKS command.
|
||||||
|
type Command int
|
||||||
|
|
||||||
|
func (cmd Command) String() string {
|
||||||
|
switch cmd {
|
||||||
|
case CmdConnect:
|
||||||
|
return "socks connect"
|
||||||
|
case cmdBind:
|
||||||
|
return "socks bind"
|
||||||
|
default:
|
||||||
|
return "socks " + strconv.Itoa(int(cmd))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// An AuthMethod represents a SOCKS authentication method.
|
||||||
|
type AuthMethod int
|
||||||
|
|
||||||
|
// A Reply represents a SOCKS command reply code.
|
||||||
|
type Reply int
|
||||||
|
|
||||||
|
func (code Reply) String() string {
|
||||||
|
switch code {
|
||||||
|
case StatusSucceeded:
|
||||||
|
return "succeeded"
|
||||||
|
case 0x01:
|
||||||
|
return "general SOCKS server failure"
|
||||||
|
case 0x02:
|
||||||
|
return "connection not allowed by ruleset"
|
||||||
|
case 0x03:
|
||||||
|
return "network unreachable"
|
||||||
|
case 0x04:
|
||||||
|
return "host unreachable"
|
||||||
|
case 0x05:
|
||||||
|
return "connection refused"
|
||||||
|
case 0x06:
|
||||||
|
return "TTL expired"
|
||||||
|
case 0x07:
|
||||||
|
return "command not supported"
|
||||||
|
case 0x08:
|
||||||
|
return "address type not supported"
|
||||||
|
default:
|
||||||
|
return "unknown code: " + strconv.Itoa(int(code))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wire protocol constants.
|
||||||
|
const (
|
||||||
|
Version5 = 0x05
|
||||||
|
|
||||||
|
AddrTypeIPv4 = 0x01
|
||||||
|
AddrTypeFQDN = 0x03
|
||||||
|
AddrTypeIPv6 = 0x04
|
||||||
|
|
||||||
|
CmdConnect Command = 0x01 // establishes an active-open forward proxy connection
|
||||||
|
cmdBind Command = 0x02 // establishes a passive-open forward proxy connection
|
||||||
|
|
||||||
|
AuthMethodNotRequired AuthMethod = 0x00 // no authentication required
|
||||||
|
AuthMethodUsernamePassword AuthMethod = 0x02 // use username/password
|
||||||
|
AuthMethodNoAcceptableMethods AuthMethod = 0xff // no acceptable authentication methods
|
||||||
|
|
||||||
|
StatusSucceeded Reply = 0x00
|
||||||
|
)
|
||||||
|
|
||||||
|
// An Addr represents a SOCKS-specific address.
|
||||||
|
// Either Name or IP is used exclusively.
|
||||||
|
type Addr struct {
|
||||||
|
Name string // fully-qualified domain name
|
||||||
|
IP net.IP
|
||||||
|
Port int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *Addr) Network() string { return "socks" }
|
||||||
|
|
||||||
|
func (a *Addr) String() string {
|
||||||
|
if a == nil {
|
||||||
|
return "<nil>"
|
||||||
|
}
|
||||||
|
port := strconv.Itoa(a.Port)
|
||||||
|
if a.IP == nil {
|
||||||
|
return net.JoinHostPort(a.Name, port)
|
||||||
|
}
|
||||||
|
return net.JoinHostPort(a.IP.String(), port)
|
||||||
|
}
|
||||||
|
|
||||||
|
// A Conn represents a forward proxy connection.
|
||||||
|
type Conn struct {
|
||||||
|
net.Conn
|
||||||
|
|
||||||
|
boundAddr net.Addr
|
||||||
|
}
|
||||||
|
|
||||||
|
// BoundAddr returns the address assigned by the proxy server for
|
||||||
|
// connecting to the command target address from the proxy server.
|
||||||
|
func (c *Conn) BoundAddr() net.Addr {
|
||||||
|
if c == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return c.boundAddr
|
||||||
|
}
|
||||||
|
|
||||||
|
// A Dialer holds SOCKS-specific options.
|
||||||
|
type Dialer struct {
|
||||||
|
cmd Command // either CmdConnect or cmdBind
|
||||||
|
proxyNetwork string // network between a proxy server and a client
|
||||||
|
proxyAddress string // proxy server address
|
||||||
|
|
||||||
|
// ProxyDial specifies the optional dial function for
|
||||||
|
// establishing the transport connection.
|
||||||
|
ProxyDial func(context.Context, string, string) (net.Conn, error)
|
||||||
|
|
||||||
|
// AuthMethods specifies the list of request authentication
|
||||||
|
// methods.
|
||||||
|
// If empty, SOCKS client requests only AuthMethodNotRequired.
|
||||||
|
AuthMethods []AuthMethod
|
||||||
|
|
||||||
|
// Authenticate specifies the optional authentication
|
||||||
|
// function. It must be non-nil when AuthMethods is not empty.
|
||||||
|
// It must return an error when the authentication is failed.
|
||||||
|
Authenticate func(context.Context, io.ReadWriter, AuthMethod) error
|
||||||
|
}
|
||||||
|
|
||||||
|
// DialContext connects to the provided address on the provided
|
||||||
|
// network.
|
||||||
|
//
|
||||||
|
// The returned error value may be a net.OpError. When the Op field of
|
||||||
|
// net.OpError contains "socks", the Source field contains a proxy
|
||||||
|
// server address and the Addr field contains a command target
|
||||||
|
// address.
|
||||||
|
//
|
||||||
|
// See func Dial of the net package of standard library for a
|
||||||
|
// description of the network and address parameters.
|
||||||
|
func (d *Dialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) {
|
||||||
|
if err := d.validateTarget(network, address); err != nil {
|
||||||
|
proxy, dst, _ := d.pathAddrs(address)
|
||||||
|
return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err}
|
||||||
|
}
|
||||||
|
if ctx == nil {
|
||||||
|
proxy, dst, _ := d.pathAddrs(address)
|
||||||
|
return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: errors.New("nil context")}
|
||||||
|
}
|
||||||
|
var err error
|
||||||
|
var c net.Conn
|
||||||
|
if d.ProxyDial != nil {
|
||||||
|
c, err = d.ProxyDial(ctx, d.proxyNetwork, d.proxyAddress)
|
||||||
|
} else {
|
||||||
|
var dd net.Dialer
|
||||||
|
c, err = dd.DialContext(ctx, d.proxyNetwork, d.proxyAddress)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
proxy, dst, _ := d.pathAddrs(address)
|
||||||
|
return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err}
|
||||||
|
}
|
||||||
|
a, err := d.connect(ctx, c, address)
|
||||||
|
if err != nil {
|
||||||
|
c.Close()
|
||||||
|
proxy, dst, _ := d.pathAddrs(address)
|
||||||
|
return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err}
|
||||||
|
}
|
||||||
|
return &Conn{Conn: c, boundAddr: a}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DialWithConn initiates a connection from SOCKS server to the target
|
||||||
|
// network and address using the connection c that is already
|
||||||
|
// connected to the SOCKS server.
|
||||||
|
//
|
||||||
|
// It returns the connection's local address assigned by the SOCKS
|
||||||
|
// server.
|
||||||
|
func (d *Dialer) DialWithConn(ctx context.Context, c net.Conn, network, address string) (net.Addr, error) {
|
||||||
|
if err := d.validateTarget(network, address); err != nil {
|
||||||
|
proxy, dst, _ := d.pathAddrs(address)
|
||||||
|
return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err}
|
||||||
|
}
|
||||||
|
if ctx == nil {
|
||||||
|
proxy, dst, _ := d.pathAddrs(address)
|
||||||
|
return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: errors.New("nil context")}
|
||||||
|
}
|
||||||
|
a, err := d.connect(ctx, c, address)
|
||||||
|
if err != nil {
|
||||||
|
proxy, dst, _ := d.pathAddrs(address)
|
||||||
|
return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err}
|
||||||
|
}
|
||||||
|
return a, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dial connects to the provided address on the provided network.
|
||||||
|
//
|
||||||
|
// Unlike DialContext, it returns a raw transport connection instead
|
||||||
|
// of a forward proxy connection.
|
||||||
|
//
|
||||||
|
// Deprecated: Use DialContext or DialWithConn instead.
|
||||||
|
func (d *Dialer) Dial(network, address string) (net.Conn, error) {
|
||||||
|
if err := d.validateTarget(network, address); err != nil {
|
||||||
|
proxy, dst, _ := d.pathAddrs(address)
|
||||||
|
return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err}
|
||||||
|
}
|
||||||
|
var err error
|
||||||
|
var c net.Conn
|
||||||
|
if d.ProxyDial != nil {
|
||||||
|
c, err = d.ProxyDial(context.Background(), d.proxyNetwork, d.proxyAddress)
|
||||||
|
} else {
|
||||||
|
c, err = net.Dial(d.proxyNetwork, d.proxyAddress)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
proxy, dst, _ := d.pathAddrs(address)
|
||||||
|
return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err}
|
||||||
|
}
|
||||||
|
if _, err := d.DialWithConn(context.Background(), c, network, address); err != nil {
|
||||||
|
c.Close()
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return c, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Dialer) validateTarget(network, address string) error {
|
||||||
|
switch network {
|
||||||
|
case "tcp", "tcp6", "tcp4":
|
||||||
|
default:
|
||||||
|
return errors.New("network not implemented")
|
||||||
|
}
|
||||||
|
switch d.cmd {
|
||||||
|
case CmdConnect, cmdBind:
|
||||||
|
default:
|
||||||
|
return errors.New("command not implemented")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Dialer) pathAddrs(address string) (proxy, dst net.Addr, err error) {
|
||||||
|
for i, s := range []string{d.proxyAddress, address} {
|
||||||
|
host, port, err := splitHostPort(s)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
a := &Addr{Port: port}
|
||||||
|
a.IP = net.ParseIP(host)
|
||||||
|
if a.IP == nil {
|
||||||
|
a.Name = host
|
||||||
|
}
|
||||||
|
if i == 0 {
|
||||||
|
proxy = a
|
||||||
|
} else {
|
||||||
|
dst = a
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewDialer returns a new Dialer that dials through the provided
|
||||||
|
// proxy server's network and address.
|
||||||
|
func NewDialer(network, address string) *Dialer {
|
||||||
|
return &Dialer{proxyNetwork: network, proxyAddress: address, cmd: CmdConnect}
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
authUsernamePasswordVersion = 0x01
|
||||||
|
authStatusSucceeded = 0x00
|
||||||
|
)
|
||||||
|
|
||||||
|
// UsernamePassword are the credentials for the username/password
|
||||||
|
// authentication method.
|
||||||
|
type UsernamePassword struct {
|
||||||
|
Username string
|
||||||
|
Password string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Authenticate authenticates a pair of username and password with the
|
||||||
|
// proxy server.
|
||||||
|
func (up *UsernamePassword) Authenticate(ctx context.Context, rw io.ReadWriter, auth AuthMethod) error {
|
||||||
|
switch auth {
|
||||||
|
case AuthMethodNotRequired:
|
||||||
|
return nil
|
||||||
|
case AuthMethodUsernamePassword:
|
||||||
|
if len(up.Username) == 0 || len(up.Username) > 255 || len(up.Password) == 0 || len(up.Password) > 255 {
|
||||||
|
return errors.New("invalid username/password")
|
||||||
|
}
|
||||||
|
b := []byte{authUsernamePasswordVersion}
|
||||||
|
b = append(b, byte(len(up.Username)))
|
||||||
|
b = append(b, up.Username...)
|
||||||
|
b = append(b, byte(len(up.Password)))
|
||||||
|
b = append(b, up.Password...)
|
||||||
|
// TODO(mikio): handle IO deadlines and cancelation if
|
||||||
|
// necessary
|
||||||
|
if _, err := rw.Write(b); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if _, err := io.ReadFull(rw, b[:2]); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if b[0] != authUsernamePasswordVersion {
|
||||||
|
return errors.New("invalid username/password version")
|
||||||
|
}
|
||||||
|
if b[1] != authStatusSucceeded {
|
||||||
|
return errors.New("username/password authentication failed")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return errors.New("unsupported authentication method " + strconv.Itoa(int(auth)))
|
||||||
|
}
|
54
vendor/golang.org/x/net/proxy/dial.go
generated
vendored
Normal file
54
vendor/golang.org/x/net/proxy/dial.go
generated
vendored
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
// Copyright 2019 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package proxy
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"net"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A ContextDialer dials using a context.
|
||||||
|
type ContextDialer interface {
|
||||||
|
DialContext(ctx context.Context, network, address string) (net.Conn, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dial works like DialContext on net.Dialer but using a dialer returned by FromEnvironment.
|
||||||
|
//
|
||||||
|
// The passed ctx is only used for returning the Conn, not the lifetime of the Conn.
|
||||||
|
//
|
||||||
|
// Custom dialers (registered via RegisterDialerType) that do not implement ContextDialer
|
||||||
|
// can leak a goroutine for as long as it takes the underlying Dialer implementation to timeout.
|
||||||
|
//
|
||||||
|
// A Conn returned from a successful Dial after the context has been cancelled will be immediately closed.
|
||||||
|
func Dial(ctx context.Context, network, address string) (net.Conn, error) {
|
||||||
|
d := FromEnvironment()
|
||||||
|
if xd, ok := d.(ContextDialer); ok {
|
||||||
|
return xd.DialContext(ctx, network, address)
|
||||||
|
}
|
||||||
|
return dialContext(ctx, d, network, address)
|
||||||
|
}
|
||||||
|
|
||||||
|
// WARNING: this can leak a goroutine for as long as the underlying Dialer implementation takes to timeout
|
||||||
|
// A Conn returned from a successful Dial after the context has been cancelled will be immediately closed.
|
||||||
|
func dialContext(ctx context.Context, d Dialer, network, address string) (net.Conn, error) {
|
||||||
|
var (
|
||||||
|
conn net.Conn
|
||||||
|
done = make(chan struct{}, 1)
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
go func() {
|
||||||
|
conn, err = d.Dial(network, address)
|
||||||
|
close(done)
|
||||||
|
if conn != nil && ctx.Err() != nil {
|
||||||
|
conn.Close()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
err = ctx.Err()
|
||||||
|
case <-done:
|
||||||
|
}
|
||||||
|
return conn, err
|
||||||
|
}
|
31
vendor/golang.org/x/net/proxy/direct.go
generated
vendored
Normal file
31
vendor/golang.org/x/net/proxy/direct.go
generated
vendored
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
// Copyright 2011 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package proxy
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"net"
|
||||||
|
)
|
||||||
|
|
||||||
|
type direct struct{}
|
||||||
|
|
||||||
|
// Direct implements Dialer by making network connections directly using net.Dial or net.DialContext.
|
||||||
|
var Direct = direct{}
|
||||||
|
|
||||||
|
var (
|
||||||
|
_ Dialer = Direct
|
||||||
|
_ ContextDialer = Direct
|
||||||
|
)
|
||||||
|
|
||||||
|
// Dial directly invokes net.Dial with the supplied parameters.
|
||||||
|
func (direct) Dial(network, addr string) (net.Conn, error) {
|
||||||
|
return net.Dial(network, addr)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DialContext instantiates a net.Dialer and invokes its DialContext receiver with the supplied parameters.
|
||||||
|
func (direct) DialContext(ctx context.Context, network, addr string) (net.Conn, error) {
|
||||||
|
var d net.Dialer
|
||||||
|
return d.DialContext(ctx, network, addr)
|
||||||
|
}
|
155
vendor/golang.org/x/net/proxy/per_host.go
generated
vendored
Normal file
155
vendor/golang.org/x/net/proxy/per_host.go
generated
vendored
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
// Copyright 2011 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package proxy
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"net"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A PerHost directs connections to a default Dialer unless the host name
|
||||||
|
// requested matches one of a number of exceptions.
|
||||||
|
type PerHost struct {
|
||||||
|
def, bypass Dialer
|
||||||
|
|
||||||
|
bypassNetworks []*net.IPNet
|
||||||
|
bypassIPs []net.IP
|
||||||
|
bypassZones []string
|
||||||
|
bypassHosts []string
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewPerHost returns a PerHost Dialer that directs connections to either
|
||||||
|
// defaultDialer or bypass, depending on whether the connection matches one of
|
||||||
|
// the configured rules.
|
||||||
|
func NewPerHost(defaultDialer, bypass Dialer) *PerHost {
|
||||||
|
return &PerHost{
|
||||||
|
def: defaultDialer,
|
||||||
|
bypass: bypass,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dial connects to the address addr on the given network through either
|
||||||
|
// defaultDialer or bypass.
|
||||||
|
func (p *PerHost) Dial(network, addr string) (c net.Conn, err error) {
|
||||||
|
host, _, err := net.SplitHostPort(addr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return p.dialerForRequest(host).Dial(network, addr)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DialContext connects to the address addr on the given network through either
|
||||||
|
// defaultDialer or bypass.
|
||||||
|
func (p *PerHost) DialContext(ctx context.Context, network, addr string) (c net.Conn, err error) {
|
||||||
|
host, _, err := net.SplitHostPort(addr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
d := p.dialerForRequest(host)
|
||||||
|
if x, ok := d.(ContextDialer); ok {
|
||||||
|
return x.DialContext(ctx, network, addr)
|
||||||
|
}
|
||||||
|
return dialContext(ctx, d, network, addr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PerHost) dialerForRequest(host string) Dialer {
|
||||||
|
if ip := net.ParseIP(host); ip != nil {
|
||||||
|
for _, net := range p.bypassNetworks {
|
||||||
|
if net.Contains(ip) {
|
||||||
|
return p.bypass
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, bypassIP := range p.bypassIPs {
|
||||||
|
if bypassIP.Equal(ip) {
|
||||||
|
return p.bypass
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return p.def
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, zone := range p.bypassZones {
|
||||||
|
if strings.HasSuffix(host, zone) {
|
||||||
|
return p.bypass
|
||||||
|
}
|
||||||
|
if host == zone[1:] {
|
||||||
|
// For a zone ".example.com", we match "example.com"
|
||||||
|
// too.
|
||||||
|
return p.bypass
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, bypassHost := range p.bypassHosts {
|
||||||
|
if bypassHost == host {
|
||||||
|
return p.bypass
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return p.def
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddFromString parses a string that contains comma-separated values
|
||||||
|
// specifying hosts that should use the bypass proxy. Each value is either an
|
||||||
|
// IP address, a CIDR range, a zone (*.example.com) or a host name
|
||||||
|
// (localhost). A best effort is made to parse the string and errors are
|
||||||
|
// ignored.
|
||||||
|
func (p *PerHost) AddFromString(s string) {
|
||||||
|
hosts := strings.Split(s, ",")
|
||||||
|
for _, host := range hosts {
|
||||||
|
host = strings.TrimSpace(host)
|
||||||
|
if len(host) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if strings.Contains(host, "/") {
|
||||||
|
// We assume that it's a CIDR address like 127.0.0.0/8
|
||||||
|
if _, net, err := net.ParseCIDR(host); err == nil {
|
||||||
|
p.AddNetwork(net)
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if ip := net.ParseIP(host); ip != nil {
|
||||||
|
p.AddIP(ip)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if strings.HasPrefix(host, "*.") {
|
||||||
|
p.AddZone(host[1:])
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
p.AddHost(host)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddIP specifies an IP address that will use the bypass proxy. Note that
|
||||||
|
// this will only take effect if a literal IP address is dialed. A connection
|
||||||
|
// to a named host will never match an IP.
|
||||||
|
func (p *PerHost) AddIP(ip net.IP) {
|
||||||
|
p.bypassIPs = append(p.bypassIPs, ip)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddNetwork specifies an IP range that will use the bypass proxy. Note that
|
||||||
|
// this will only take effect if a literal IP address is dialed. A connection
|
||||||
|
// to a named host will never match.
|
||||||
|
func (p *PerHost) AddNetwork(net *net.IPNet) {
|
||||||
|
p.bypassNetworks = append(p.bypassNetworks, net)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddZone specifies a DNS suffix that will use the bypass proxy. A zone of
|
||||||
|
// "example.com" matches "example.com" and all of its subdomains.
|
||||||
|
func (p *PerHost) AddZone(zone string) {
|
||||||
|
if strings.HasSuffix(zone, ".") {
|
||||||
|
zone = zone[:len(zone)-1]
|
||||||
|
}
|
||||||
|
if !strings.HasPrefix(zone, ".") {
|
||||||
|
zone = "." + zone
|
||||||
|
}
|
||||||
|
p.bypassZones = append(p.bypassZones, zone)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddHost specifies a host name that will use the bypass proxy.
|
||||||
|
func (p *PerHost) AddHost(host string) {
|
||||||
|
if strings.HasSuffix(host, ".") {
|
||||||
|
host = host[:len(host)-1]
|
||||||
|
}
|
||||||
|
p.bypassHosts = append(p.bypassHosts, host)
|
||||||
|
}
|
149
vendor/golang.org/x/net/proxy/proxy.go
generated
vendored
Normal file
149
vendor/golang.org/x/net/proxy/proxy.go
generated
vendored
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
// Copyright 2011 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Package proxy provides support for a variety of protocols to proxy network
|
||||||
|
// data.
|
||||||
|
package proxy // import "golang.org/x/net/proxy"
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"net"
|
||||||
|
"net/url"
|
||||||
|
"os"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A Dialer is a means to establish a connection.
|
||||||
|
// Custom dialers should also implement ContextDialer.
|
||||||
|
type Dialer interface {
|
||||||
|
// Dial connects to the given address via the proxy.
|
||||||
|
Dial(network, addr string) (c net.Conn, err error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Auth contains authentication parameters that specific Dialers may require.
|
||||||
|
type Auth struct {
|
||||||
|
User, Password string
|
||||||
|
}
|
||||||
|
|
||||||
|
// FromEnvironment returns the dialer specified by the proxy-related
|
||||||
|
// variables in the environment and makes underlying connections
|
||||||
|
// directly.
|
||||||
|
func FromEnvironment() Dialer {
|
||||||
|
return FromEnvironmentUsing(Direct)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FromEnvironmentUsing returns the dialer specify by the proxy-related
|
||||||
|
// variables in the environment and makes underlying connections
|
||||||
|
// using the provided forwarding Dialer (for instance, a *net.Dialer
|
||||||
|
// with desired configuration).
|
||||||
|
func FromEnvironmentUsing(forward Dialer) Dialer {
|
||||||
|
allProxy := allProxyEnv.Get()
|
||||||
|
if len(allProxy) == 0 {
|
||||||
|
return forward
|
||||||
|
}
|
||||||
|
|
||||||
|
proxyURL, err := url.Parse(allProxy)
|
||||||
|
if err != nil {
|
||||||
|
return forward
|
||||||
|
}
|
||||||
|
proxy, err := FromURL(proxyURL, forward)
|
||||||
|
if err != nil {
|
||||||
|
return forward
|
||||||
|
}
|
||||||
|
|
||||||
|
noProxy := noProxyEnv.Get()
|
||||||
|
if len(noProxy) == 0 {
|
||||||
|
return proxy
|
||||||
|
}
|
||||||
|
|
||||||
|
perHost := NewPerHost(proxy, forward)
|
||||||
|
perHost.AddFromString(noProxy)
|
||||||
|
return perHost
|
||||||
|
}
|
||||||
|
|
||||||
|
// proxySchemes is a map from URL schemes to a function that creates a Dialer
|
||||||
|
// from a URL with such a scheme.
|
||||||
|
var proxySchemes map[string]func(*url.URL, Dialer) (Dialer, error)
|
||||||
|
|
||||||
|
// RegisterDialerType takes a URL scheme and a function to generate Dialers from
|
||||||
|
// a URL with that scheme and a forwarding Dialer. Registered schemes are used
|
||||||
|
// by FromURL.
|
||||||
|
func RegisterDialerType(scheme string, f func(*url.URL, Dialer) (Dialer, error)) {
|
||||||
|
if proxySchemes == nil {
|
||||||
|
proxySchemes = make(map[string]func(*url.URL, Dialer) (Dialer, error))
|
||||||
|
}
|
||||||
|
proxySchemes[scheme] = f
|
||||||
|
}
|
||||||
|
|
||||||
|
// FromURL returns a Dialer given a URL specification and an underlying
|
||||||
|
// Dialer for it to make network requests.
|
||||||
|
func FromURL(u *url.URL, forward Dialer) (Dialer, error) {
|
||||||
|
var auth *Auth
|
||||||
|
if u.User != nil {
|
||||||
|
auth = new(Auth)
|
||||||
|
auth.User = u.User.Username()
|
||||||
|
if p, ok := u.User.Password(); ok {
|
||||||
|
auth.Password = p
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch u.Scheme {
|
||||||
|
case "socks5", "socks5h":
|
||||||
|
addr := u.Hostname()
|
||||||
|
port := u.Port()
|
||||||
|
if port == "" {
|
||||||
|
port = "1080"
|
||||||
|
}
|
||||||
|
return SOCKS5("tcp", net.JoinHostPort(addr, port), auth, forward)
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the scheme doesn't match any of the built-in schemes, see if it
|
||||||
|
// was registered by another package.
|
||||||
|
if proxySchemes != nil {
|
||||||
|
if f, ok := proxySchemes[u.Scheme]; ok {
|
||||||
|
return f(u, forward)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, errors.New("proxy: unknown scheme: " + u.Scheme)
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
allProxyEnv = &envOnce{
|
||||||
|
names: []string{"ALL_PROXY", "all_proxy"},
|
||||||
|
}
|
||||||
|
noProxyEnv = &envOnce{
|
||||||
|
names: []string{"NO_PROXY", "no_proxy"},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// envOnce looks up an environment variable (optionally by multiple
|
||||||
|
// names) once. It mitigates expensive lookups on some platforms
|
||||||
|
// (e.g. Windows).
|
||||||
|
// (Borrowed from net/http/transport.go)
|
||||||
|
type envOnce struct {
|
||||||
|
names []string
|
||||||
|
once sync.Once
|
||||||
|
val string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *envOnce) Get() string {
|
||||||
|
e.once.Do(e.init)
|
||||||
|
return e.val
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *envOnce) init() {
|
||||||
|
for _, n := range e.names {
|
||||||
|
e.val = os.Getenv(n)
|
||||||
|
if e.val != "" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// reset is used by tests
|
||||||
|
func (e *envOnce) reset() {
|
||||||
|
e.once = sync.Once{}
|
||||||
|
e.val = ""
|
||||||
|
}
|
42
vendor/golang.org/x/net/proxy/socks5.go
generated
vendored
Normal file
42
vendor/golang.org/x/net/proxy/socks5.go
generated
vendored
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
// Copyright 2011 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package proxy
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"net"
|
||||||
|
|
||||||
|
"golang.org/x/net/internal/socks"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SOCKS5 returns a Dialer that makes SOCKSv5 connections to the given
|
||||||
|
// address with an optional username and password.
|
||||||
|
// See RFC 1928 and RFC 1929.
|
||||||
|
func SOCKS5(network, address string, auth *Auth, forward Dialer) (Dialer, error) {
|
||||||
|
d := socks.NewDialer(network, address)
|
||||||
|
if forward != nil {
|
||||||
|
if f, ok := forward.(ContextDialer); ok {
|
||||||
|
d.ProxyDial = func(ctx context.Context, network string, address string) (net.Conn, error) {
|
||||||
|
return f.DialContext(ctx, network, address)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
d.ProxyDial = func(ctx context.Context, network string, address string) (net.Conn, error) {
|
||||||
|
return dialContext(ctx, forward, network, address)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if auth != nil {
|
||||||
|
up := socks.UsernamePassword{
|
||||||
|
Username: auth.User,
|
||||||
|
Password: auth.Password,
|
||||||
|
}
|
||||||
|
d.AuthMethods = []socks.AuthMethod{
|
||||||
|
socks.AuthMethodNotRequired,
|
||||||
|
socks.AuthMethodUsernamePassword,
|
||||||
|
}
|
||||||
|
d.Authenticate = up.Authenticate
|
||||||
|
}
|
||||||
|
return d, nil
|
||||||
|
}
|
3
vendor/golang.org/x/sys/AUTHORS
generated
vendored
Normal file
3
vendor/golang.org/x/sys/AUTHORS
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# This source code refers to The Go Authors for copyright purposes.
|
||||||
|
# The master list of authors is in the main Go distribution,
|
||||||
|
# visible at http://tip.golang.org/AUTHORS.
|
3
vendor/golang.org/x/sys/CONTRIBUTORS
generated
vendored
Normal file
3
vendor/golang.org/x/sys/CONTRIBUTORS
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# This source code was written by the Go contributors.
|
||||||
|
# The master list of contributors is in the main Go distribution,
|
||||||
|
# visible at http://tip.golang.org/CONTRIBUTORS.
|
27
vendor/golang.org/x/sys/LICENSE
generated
vendored
Normal file
27
vendor/golang.org/x/sys/LICENSE
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
Copyright (c) 2009 The Go Authors. All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* 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.
|
||||||
|
* Neither the name of Google Inc. nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
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
|
||||||
|
OWNER 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.
|
22
vendor/golang.org/x/sys/PATENTS
generated
vendored
Normal file
22
vendor/golang.org/x/sys/PATENTS
generated
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
Additional IP Rights Grant (Patents)
|
||||||
|
|
||||||
|
"This implementation" means the copyrightable works distributed by
|
||||||
|
Google as part of the Go project.
|
||||||
|
|
||||||
|
Google hereby grants to You a perpetual, worldwide, non-exclusive,
|
||||||
|
no-charge, royalty-free, irrevocable (except as stated in this section)
|
||||||
|
patent license to make, have made, use, offer to sell, sell, import,
|
||||||
|
transfer and otherwise run, modify and propagate the contents of this
|
||||||
|
implementation of Go, where such license applies only to those patent
|
||||||
|
claims, both currently owned or controlled by Google and acquired in
|
||||||
|
the future, licensable by Google that are necessarily infringed by this
|
||||||
|
implementation of Go. This grant does not include claims that would be
|
||||||
|
infringed only as a consequence of further modification of this
|
||||||
|
implementation. If you or your agent or exclusive licensee institute or
|
||||||
|
order or agree to the institution of patent litigation against any
|
||||||
|
entity (including a cross-claim or counterclaim in a lawsuit) alleging
|
||||||
|
that this implementation of Go or any code incorporated within this
|
||||||
|
implementation of Go constitutes direct or contributory patent
|
||||||
|
infringement, or inducement of patent infringement, then any patent
|
||||||
|
rights granted to you under this License for this implementation of Go
|
||||||
|
shall terminate as of the date such litigation is filed.
|
17
vendor/golang.org/x/sys/cpu/asm_aix_ppc64.s
generated
vendored
Normal file
17
vendor/golang.org/x/sys/cpu/asm_aix_ppc64.s
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build gc
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// System calls for ppc64, AIX are implemented in runtime/syscall_aix.go
|
||||||
|
//
|
||||||
|
|
||||||
|
TEXT ·syscall6(SB),NOSPLIT,$0-88
|
||||||
|
JMP syscall·syscall6(SB)
|
||||||
|
|
||||||
|
TEXT ·rawSyscall6(SB),NOSPLIT,$0-88
|
||||||
|
JMP syscall·rawSyscall6(SB)
|
65
vendor/golang.org/x/sys/cpu/byteorder.go
generated
vendored
Normal file
65
vendor/golang.org/x/sys/cpu/byteorder.go
generated
vendored
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
// Copyright 2019 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package cpu
|
||||||
|
|
||||||
|
import (
|
||||||
|
"runtime"
|
||||||
|
)
|
||||||
|
|
||||||
|
// byteOrder is a subset of encoding/binary.ByteOrder.
|
||||||
|
type byteOrder interface {
|
||||||
|
Uint32([]byte) uint32
|
||||||
|
Uint64([]byte) uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
type littleEndian struct{}
|
||||||
|
type bigEndian struct{}
|
||||||
|
|
||||||
|
func (littleEndian) Uint32(b []byte) uint32 {
|
||||||
|
_ = b[3] // bounds check hint to compiler; see golang.org/issue/14808
|
||||||
|
return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
|
||||||
|
}
|
||||||
|
|
||||||
|
func (littleEndian) Uint64(b []byte) uint64 {
|
||||||
|
_ = b[7] // bounds check hint to compiler; see golang.org/issue/14808
|
||||||
|
return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 |
|
||||||
|
uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bigEndian) Uint32(b []byte) uint32 {
|
||||||
|
_ = b[3] // bounds check hint to compiler; see golang.org/issue/14808
|
||||||
|
return uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bigEndian) Uint64(b []byte) uint64 {
|
||||||
|
_ = b[7] // bounds check hint to compiler; see golang.org/issue/14808
|
||||||
|
return uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 |
|
||||||
|
uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56
|
||||||
|
}
|
||||||
|
|
||||||
|
// hostByteOrder returns littleEndian on little-endian machines and
|
||||||
|
// bigEndian on big-endian machines.
|
||||||
|
func hostByteOrder() byteOrder {
|
||||||
|
switch runtime.GOARCH {
|
||||||
|
case "386", "amd64", "amd64p32",
|
||||||
|
"alpha",
|
||||||
|
"arm", "arm64",
|
||||||
|
"mipsle", "mips64le", "mips64p32le",
|
||||||
|
"nios2",
|
||||||
|
"ppc64le",
|
||||||
|
"riscv", "riscv64",
|
||||||
|
"sh":
|
||||||
|
return littleEndian{}
|
||||||
|
case "armbe", "arm64be",
|
||||||
|
"m68k",
|
||||||
|
"mips", "mips64", "mips64p32",
|
||||||
|
"ppc", "ppc64",
|
||||||
|
"s390", "s390x",
|
||||||
|
"shbe",
|
||||||
|
"sparc", "sparc64":
|
||||||
|
return bigEndian{}
|
||||||
|
}
|
||||||
|
panic("unknown architecture")
|
||||||
|
}
|
287
vendor/golang.org/x/sys/cpu/cpu.go
generated
vendored
Normal file
287
vendor/golang.org/x/sys/cpu/cpu.go
generated
vendored
Normal file
@ -0,0 +1,287 @@
|
|||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Package cpu implements processor feature detection for
|
||||||
|
// various CPU architectures.
|
||||||
|
package cpu
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Initialized reports whether the CPU features were initialized.
|
||||||
|
//
|
||||||
|
// For some GOOS/GOARCH combinations initialization of the CPU features depends
|
||||||
|
// on reading an operating specific file, e.g. /proc/self/auxv on linux/arm
|
||||||
|
// Initialized will report false if reading the file fails.
|
||||||
|
var Initialized bool
|
||||||
|
|
||||||
|
// CacheLinePad is used to pad structs to avoid false sharing.
|
||||||
|
type CacheLinePad struct{ _ [cacheLineSize]byte }
|
||||||
|
|
||||||
|
// X86 contains the supported CPU features of the
|
||||||
|
// current X86/AMD64 platform. If the current platform
|
||||||
|
// is not X86/AMD64 then all feature flags are false.
|
||||||
|
//
|
||||||
|
// X86 is padded to avoid false sharing. Further the HasAVX
|
||||||
|
// and HasAVX2 are only set if the OS supports XMM and YMM
|
||||||
|
// registers in addition to the CPUID feature bit being set.
|
||||||
|
var X86 struct {
|
||||||
|
_ CacheLinePad
|
||||||
|
HasAES bool // AES hardware implementation (AES NI)
|
||||||
|
HasADX bool // Multi-precision add-carry instruction extensions
|
||||||
|
HasAVX bool // Advanced vector extension
|
||||||
|
HasAVX2 bool // Advanced vector extension 2
|
||||||
|
HasAVX512 bool // Advanced vector extension 512
|
||||||
|
HasAVX512F bool // Advanced vector extension 512 Foundation Instructions
|
||||||
|
HasAVX512CD bool // Advanced vector extension 512 Conflict Detection Instructions
|
||||||
|
HasAVX512ER bool // Advanced vector extension 512 Exponential and Reciprocal Instructions
|
||||||
|
HasAVX512PF bool // Advanced vector extension 512 Prefetch Instructions Instructions
|
||||||
|
HasAVX512VL bool // Advanced vector extension 512 Vector Length Extensions
|
||||||
|
HasAVX512BW bool // Advanced vector extension 512 Byte and Word Instructions
|
||||||
|
HasAVX512DQ bool // Advanced vector extension 512 Doubleword and Quadword Instructions
|
||||||
|
HasAVX512IFMA bool // Advanced vector extension 512 Integer Fused Multiply Add
|
||||||
|
HasAVX512VBMI bool // Advanced vector extension 512 Vector Byte Manipulation Instructions
|
||||||
|
HasAVX5124VNNIW bool // Advanced vector extension 512 Vector Neural Network Instructions Word variable precision
|
||||||
|
HasAVX5124FMAPS bool // Advanced vector extension 512 Fused Multiply Accumulation Packed Single precision
|
||||||
|
HasAVX512VPOPCNTDQ bool // Advanced vector extension 512 Double and quad word population count instructions
|
||||||
|
HasAVX512VPCLMULQDQ bool // Advanced vector extension 512 Vector carry-less multiply operations
|
||||||
|
HasAVX512VNNI bool // Advanced vector extension 512 Vector Neural Network Instructions
|
||||||
|
HasAVX512GFNI bool // Advanced vector extension 512 Galois field New Instructions
|
||||||
|
HasAVX512VAES bool // Advanced vector extension 512 Vector AES instructions
|
||||||
|
HasAVX512VBMI2 bool // Advanced vector extension 512 Vector Byte Manipulation Instructions 2
|
||||||
|
HasAVX512BITALG bool // Advanced vector extension 512 Bit Algorithms
|
||||||
|
HasAVX512BF16 bool // Advanced vector extension 512 BFloat16 Instructions
|
||||||
|
HasBMI1 bool // Bit manipulation instruction set 1
|
||||||
|
HasBMI2 bool // Bit manipulation instruction set 2
|
||||||
|
HasERMS bool // Enhanced REP for MOVSB and STOSB
|
||||||
|
HasFMA bool // Fused-multiply-add instructions
|
||||||
|
HasOSXSAVE bool // OS supports XSAVE/XRESTOR for saving/restoring XMM registers.
|
||||||
|
HasPCLMULQDQ bool // PCLMULQDQ instruction - most often used for AES-GCM
|
||||||
|
HasPOPCNT bool // Hamming weight instruction POPCNT.
|
||||||
|
HasRDRAND bool // RDRAND instruction (on-chip random number generator)
|
||||||
|
HasRDSEED bool // RDSEED instruction (on-chip random number generator)
|
||||||
|
HasSSE2 bool // Streaming SIMD extension 2 (always available on amd64)
|
||||||
|
HasSSE3 bool // Streaming SIMD extension 3
|
||||||
|
HasSSSE3 bool // Supplemental streaming SIMD extension 3
|
||||||
|
HasSSE41 bool // Streaming SIMD extension 4 and 4.1
|
||||||
|
HasSSE42 bool // Streaming SIMD extension 4 and 4.2
|
||||||
|
_ CacheLinePad
|
||||||
|
}
|
||||||
|
|
||||||
|
// ARM64 contains the supported CPU features of the
|
||||||
|
// current ARMv8(aarch64) platform. If the current platform
|
||||||
|
// is not arm64 then all feature flags are false.
|
||||||
|
var ARM64 struct {
|
||||||
|
_ CacheLinePad
|
||||||
|
HasFP bool // Floating-point instruction set (always available)
|
||||||
|
HasASIMD bool // Advanced SIMD (always available)
|
||||||
|
HasEVTSTRM bool // Event stream support
|
||||||
|
HasAES bool // AES hardware implementation
|
||||||
|
HasPMULL bool // Polynomial multiplication instruction set
|
||||||
|
HasSHA1 bool // SHA1 hardware implementation
|
||||||
|
HasSHA2 bool // SHA2 hardware implementation
|
||||||
|
HasCRC32 bool // CRC32 hardware implementation
|
||||||
|
HasATOMICS bool // Atomic memory operation instruction set
|
||||||
|
HasFPHP bool // Half precision floating-point instruction set
|
||||||
|
HasASIMDHP bool // Advanced SIMD half precision instruction set
|
||||||
|
HasCPUID bool // CPUID identification scheme registers
|
||||||
|
HasASIMDRDM bool // Rounding double multiply add/subtract instruction set
|
||||||
|
HasJSCVT bool // Javascript conversion from floating-point to integer
|
||||||
|
HasFCMA bool // Floating-point multiplication and addition of complex numbers
|
||||||
|
HasLRCPC bool // Release Consistent processor consistent support
|
||||||
|
HasDCPOP bool // Persistent memory support
|
||||||
|
HasSHA3 bool // SHA3 hardware implementation
|
||||||
|
HasSM3 bool // SM3 hardware implementation
|
||||||
|
HasSM4 bool // SM4 hardware implementation
|
||||||
|
HasASIMDDP bool // Advanced SIMD double precision instruction set
|
||||||
|
HasSHA512 bool // SHA512 hardware implementation
|
||||||
|
HasSVE bool // Scalable Vector Extensions
|
||||||
|
HasASIMDFHM bool // Advanced SIMD multiplication FP16 to FP32
|
||||||
|
_ CacheLinePad
|
||||||
|
}
|
||||||
|
|
||||||
|
// ARM contains the supported CPU features of the current ARM (32-bit) platform.
|
||||||
|
// All feature flags are false if:
|
||||||
|
// 1. the current platform is not arm, or
|
||||||
|
// 2. the current operating system is not Linux.
|
||||||
|
var ARM struct {
|
||||||
|
_ CacheLinePad
|
||||||
|
HasSWP bool // SWP instruction support
|
||||||
|
HasHALF bool // Half-word load and store support
|
||||||
|
HasTHUMB bool // ARM Thumb instruction set
|
||||||
|
Has26BIT bool // Address space limited to 26-bits
|
||||||
|
HasFASTMUL bool // 32-bit operand, 64-bit result multiplication support
|
||||||
|
HasFPA bool // Floating point arithmetic support
|
||||||
|
HasVFP bool // Vector floating point support
|
||||||
|
HasEDSP bool // DSP Extensions support
|
||||||
|
HasJAVA bool // Java instruction set
|
||||||
|
HasIWMMXT bool // Intel Wireless MMX technology support
|
||||||
|
HasCRUNCH bool // MaverickCrunch context switching and handling
|
||||||
|
HasTHUMBEE bool // Thumb EE instruction set
|
||||||
|
HasNEON bool // NEON instruction set
|
||||||
|
HasVFPv3 bool // Vector floating point version 3 support
|
||||||
|
HasVFPv3D16 bool // Vector floating point version 3 D8-D15
|
||||||
|
HasTLS bool // Thread local storage support
|
||||||
|
HasVFPv4 bool // Vector floating point version 4 support
|
||||||
|
HasIDIVA bool // Integer divide instruction support in ARM mode
|
||||||
|
HasIDIVT bool // Integer divide instruction support in Thumb mode
|
||||||
|
HasVFPD32 bool // Vector floating point version 3 D15-D31
|
||||||
|
HasLPAE bool // Large Physical Address Extensions
|
||||||
|
HasEVTSTRM bool // Event stream support
|
||||||
|
HasAES bool // AES hardware implementation
|
||||||
|
HasPMULL bool // Polynomial multiplication instruction set
|
||||||
|
HasSHA1 bool // SHA1 hardware implementation
|
||||||
|
HasSHA2 bool // SHA2 hardware implementation
|
||||||
|
HasCRC32 bool // CRC32 hardware implementation
|
||||||
|
_ CacheLinePad
|
||||||
|
}
|
||||||
|
|
||||||
|
// MIPS64X contains the supported CPU features of the current mips64/mips64le
|
||||||
|
// platforms. If the current platform is not mips64/mips64le or the current
|
||||||
|
// operating system is not Linux then all feature flags are false.
|
||||||
|
var MIPS64X struct {
|
||||||
|
_ CacheLinePad
|
||||||
|
HasMSA bool // MIPS SIMD architecture
|
||||||
|
_ CacheLinePad
|
||||||
|
}
|
||||||
|
|
||||||
|
// PPC64 contains the supported CPU features of the current ppc64/ppc64le platforms.
|
||||||
|
// If the current platform is not ppc64/ppc64le then all feature flags are false.
|
||||||
|
//
|
||||||
|
// For ppc64/ppc64le, it is safe to check only for ISA level starting on ISA v3.00,
|
||||||
|
// since there are no optional categories. There are some exceptions that also
|
||||||
|
// require kernel support to work (DARN, SCV), so there are feature bits for
|
||||||
|
// those as well. The minimum processor requirement is POWER8 (ISA 2.07).
|
||||||
|
// The struct is padded to avoid false sharing.
|
||||||
|
var PPC64 struct {
|
||||||
|
_ CacheLinePad
|
||||||
|
HasDARN bool // Hardware random number generator (requires kernel enablement)
|
||||||
|
HasSCV bool // Syscall vectored (requires kernel enablement)
|
||||||
|
IsPOWER8 bool // ISA v2.07 (POWER8)
|
||||||
|
IsPOWER9 bool // ISA v3.00 (POWER9)
|
||||||
|
_ CacheLinePad
|
||||||
|
}
|
||||||
|
|
||||||
|
// S390X contains the supported CPU features of the current IBM Z
|
||||||
|
// (s390x) platform. If the current platform is not IBM Z then all
|
||||||
|
// feature flags are false.
|
||||||
|
//
|
||||||
|
// S390X is padded to avoid false sharing. Further HasVX is only set
|
||||||
|
// if the OS supports vector registers in addition to the STFLE
|
||||||
|
// feature bit being set.
|
||||||
|
var S390X struct {
|
||||||
|
_ CacheLinePad
|
||||||
|
HasZARCH bool // z/Architecture mode is active [mandatory]
|
||||||
|
HasSTFLE bool // store facility list extended
|
||||||
|
HasLDISP bool // long (20-bit) displacements
|
||||||
|
HasEIMM bool // 32-bit immediates
|
||||||
|
HasDFP bool // decimal floating point
|
||||||
|
HasETF3EH bool // ETF-3 enhanced
|
||||||
|
HasMSA bool // message security assist (CPACF)
|
||||||
|
HasAES bool // KM-AES{128,192,256} functions
|
||||||
|
HasAESCBC bool // KMC-AES{128,192,256} functions
|
||||||
|
HasAESCTR bool // KMCTR-AES{128,192,256} functions
|
||||||
|
HasAESGCM bool // KMA-GCM-AES{128,192,256} functions
|
||||||
|
HasGHASH bool // KIMD-GHASH function
|
||||||
|
HasSHA1 bool // K{I,L}MD-SHA-1 functions
|
||||||
|
HasSHA256 bool // K{I,L}MD-SHA-256 functions
|
||||||
|
HasSHA512 bool // K{I,L}MD-SHA-512 functions
|
||||||
|
HasSHA3 bool // K{I,L}MD-SHA3-{224,256,384,512} and K{I,L}MD-SHAKE-{128,256} functions
|
||||||
|
HasVX bool // vector facility
|
||||||
|
HasVXE bool // vector-enhancements facility 1
|
||||||
|
_ CacheLinePad
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
archInit()
|
||||||
|
initOptions()
|
||||||
|
processOptions()
|
||||||
|
}
|
||||||
|
|
||||||
|
// options contains the cpu debug options that can be used in GODEBUG.
|
||||||
|
// Options are arch dependent and are added by the arch specific initOptions functions.
|
||||||
|
// Features that are mandatory for the specific GOARCH should have the Required field set
|
||||||
|
// (e.g. SSE2 on amd64).
|
||||||
|
var options []option
|
||||||
|
|
||||||
|
// Option names should be lower case. e.g. avx instead of AVX.
|
||||||
|
type option struct {
|
||||||
|
Name string
|
||||||
|
Feature *bool
|
||||||
|
Specified bool // whether feature value was specified in GODEBUG
|
||||||
|
Enable bool // whether feature should be enabled
|
||||||
|
Required bool // whether feature is mandatory and can not be disabled
|
||||||
|
}
|
||||||
|
|
||||||
|
func processOptions() {
|
||||||
|
env := os.Getenv("GODEBUG")
|
||||||
|
field:
|
||||||
|
for env != "" {
|
||||||
|
field := ""
|
||||||
|
i := strings.IndexByte(env, ',')
|
||||||
|
if i < 0 {
|
||||||
|
field, env = env, ""
|
||||||
|
} else {
|
||||||
|
field, env = env[:i], env[i+1:]
|
||||||
|
}
|
||||||
|
if len(field) < 4 || field[:4] != "cpu." {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
i = strings.IndexByte(field, '=')
|
||||||
|
if i < 0 {
|
||||||
|
print("GODEBUG sys/cpu: no value specified for \"", field, "\"\n")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
key, value := field[4:i], field[i+1:] // e.g. "SSE2", "on"
|
||||||
|
|
||||||
|
var enable bool
|
||||||
|
switch value {
|
||||||
|
case "on":
|
||||||
|
enable = true
|
||||||
|
case "off":
|
||||||
|
enable = false
|
||||||
|
default:
|
||||||
|
print("GODEBUG sys/cpu: value \"", value, "\" not supported for cpu option \"", key, "\"\n")
|
||||||
|
continue field
|
||||||
|
}
|
||||||
|
|
||||||
|
if key == "all" {
|
||||||
|
for i := range options {
|
||||||
|
options[i].Specified = true
|
||||||
|
options[i].Enable = enable || options[i].Required
|
||||||
|
}
|
||||||
|
continue field
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := range options {
|
||||||
|
if options[i].Name == key {
|
||||||
|
options[i].Specified = true
|
||||||
|
options[i].Enable = enable
|
||||||
|
continue field
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
print("GODEBUG sys/cpu: unknown cpu feature \"", key, "\"\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, o := range options {
|
||||||
|
if !o.Specified {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if o.Enable && !*o.Feature {
|
||||||
|
print("GODEBUG sys/cpu: can not enable \"", o.Name, "\", missing CPU support\n")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if !o.Enable && o.Required {
|
||||||
|
print("GODEBUG sys/cpu: can not disable \"", o.Name, "\", required CPU feature\n")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
*o.Feature = o.Enable
|
||||||
|
}
|
||||||
|
}
|
32
vendor/golang.org/x/sys/cpu/cpu_aix.go
generated
vendored
Normal file
32
vendor/golang.org/x/sys/cpu/cpu_aix.go
generated
vendored
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
// Copyright 2019 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build aix
|
||||||
|
|
||||||
|
package cpu
|
||||||
|
|
||||||
|
const (
|
||||||
|
// getsystemcfg constants
|
||||||
|
_SC_IMPL = 2
|
||||||
|
_IMPL_POWER8 = 0x10000
|
||||||
|
_IMPL_POWER9 = 0x20000
|
||||||
|
)
|
||||||
|
|
||||||
|
func archInit() {
|
||||||
|
impl := getsystemcfg(_SC_IMPL)
|
||||||
|
if impl&_IMPL_POWER8 != 0 {
|
||||||
|
PPC64.IsPOWER8 = true
|
||||||
|
}
|
||||||
|
if impl&_IMPL_POWER9 != 0 {
|
||||||
|
PPC64.IsPOWER9 = true
|
||||||
|
}
|
||||||
|
|
||||||
|
Initialized = true
|
||||||
|
}
|
||||||
|
|
||||||
|
func getsystemcfg(label int) (n uint64) {
|
||||||
|
r0, _ := callgetsystemcfg(label)
|
||||||
|
n = uint64(r0)
|
||||||
|
return
|
||||||
|
}
|
73
vendor/golang.org/x/sys/cpu/cpu_arm.go
generated
vendored
Normal file
73
vendor/golang.org/x/sys/cpu/cpu_arm.go
generated
vendored
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package cpu
|
||||||
|
|
||||||
|
const cacheLineSize = 32
|
||||||
|
|
||||||
|
// HWCAP/HWCAP2 bits.
|
||||||
|
// These are specific to Linux.
|
||||||
|
const (
|
||||||
|
hwcap_SWP = 1 << 0
|
||||||
|
hwcap_HALF = 1 << 1
|
||||||
|
hwcap_THUMB = 1 << 2
|
||||||
|
hwcap_26BIT = 1 << 3
|
||||||
|
hwcap_FAST_MULT = 1 << 4
|
||||||
|
hwcap_FPA = 1 << 5
|
||||||
|
hwcap_VFP = 1 << 6
|
||||||
|
hwcap_EDSP = 1 << 7
|
||||||
|
hwcap_JAVA = 1 << 8
|
||||||
|
hwcap_IWMMXT = 1 << 9
|
||||||
|
hwcap_CRUNCH = 1 << 10
|
||||||
|
hwcap_THUMBEE = 1 << 11
|
||||||
|
hwcap_NEON = 1 << 12
|
||||||
|
hwcap_VFPv3 = 1 << 13
|
||||||
|
hwcap_VFPv3D16 = 1 << 14
|
||||||
|
hwcap_TLS = 1 << 15
|
||||||
|
hwcap_VFPv4 = 1 << 16
|
||||||
|
hwcap_IDIVA = 1 << 17
|
||||||
|
hwcap_IDIVT = 1 << 18
|
||||||
|
hwcap_VFPD32 = 1 << 19
|
||||||
|
hwcap_LPAE = 1 << 20
|
||||||
|
hwcap_EVTSTRM = 1 << 21
|
||||||
|
|
||||||
|
hwcap2_AES = 1 << 0
|
||||||
|
hwcap2_PMULL = 1 << 1
|
||||||
|
hwcap2_SHA1 = 1 << 2
|
||||||
|
hwcap2_SHA2 = 1 << 3
|
||||||
|
hwcap2_CRC32 = 1 << 4
|
||||||
|
)
|
||||||
|
|
||||||
|
func initOptions() {
|
||||||
|
options = []option{
|
||||||
|
{Name: "pmull", Feature: &ARM.HasPMULL},
|
||||||
|
{Name: "sha1", Feature: &ARM.HasSHA1},
|
||||||
|
{Name: "sha2", Feature: &ARM.HasSHA2},
|
||||||
|
{Name: "swp", Feature: &ARM.HasSWP},
|
||||||
|
{Name: "thumb", Feature: &ARM.HasTHUMB},
|
||||||
|
{Name: "thumbee", Feature: &ARM.HasTHUMBEE},
|
||||||
|
{Name: "tls", Feature: &ARM.HasTLS},
|
||||||
|
{Name: "vfp", Feature: &ARM.HasVFP},
|
||||||
|
{Name: "vfpd32", Feature: &ARM.HasVFPD32},
|
||||||
|
{Name: "vfpv3", Feature: &ARM.HasVFPv3},
|
||||||
|
{Name: "vfpv3d16", Feature: &ARM.HasVFPv3D16},
|
||||||
|
{Name: "vfpv4", Feature: &ARM.HasVFPv4},
|
||||||
|
{Name: "half", Feature: &ARM.HasHALF},
|
||||||
|
{Name: "26bit", Feature: &ARM.Has26BIT},
|
||||||
|
{Name: "fastmul", Feature: &ARM.HasFASTMUL},
|
||||||
|
{Name: "fpa", Feature: &ARM.HasFPA},
|
||||||
|
{Name: "edsp", Feature: &ARM.HasEDSP},
|
||||||
|
{Name: "java", Feature: &ARM.HasJAVA},
|
||||||
|
{Name: "iwmmxt", Feature: &ARM.HasIWMMXT},
|
||||||
|
{Name: "crunch", Feature: &ARM.HasCRUNCH},
|
||||||
|
{Name: "neon", Feature: &ARM.HasNEON},
|
||||||
|
{Name: "idivt", Feature: &ARM.HasIDIVT},
|
||||||
|
{Name: "idiva", Feature: &ARM.HasIDIVA},
|
||||||
|
{Name: "lpae", Feature: &ARM.HasLPAE},
|
||||||
|
{Name: "evtstrm", Feature: &ARM.HasEVTSTRM},
|
||||||
|
{Name: "aes", Feature: &ARM.HasAES},
|
||||||
|
{Name: "crc32", Feature: &ARM.HasCRC32},
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
172
vendor/golang.org/x/sys/cpu/cpu_arm64.go
generated
vendored
Normal file
172
vendor/golang.org/x/sys/cpu/cpu_arm64.go
generated
vendored
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
// Copyright 2019 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package cpu
|
||||||
|
|
||||||
|
import "runtime"
|
||||||
|
|
||||||
|
const cacheLineSize = 64
|
||||||
|
|
||||||
|
func initOptions() {
|
||||||
|
options = []option{
|
||||||
|
{Name: "fp", Feature: &ARM64.HasFP},
|
||||||
|
{Name: "asimd", Feature: &ARM64.HasASIMD},
|
||||||
|
{Name: "evstrm", Feature: &ARM64.HasEVTSTRM},
|
||||||
|
{Name: "aes", Feature: &ARM64.HasAES},
|
||||||
|
{Name: "fphp", Feature: &ARM64.HasFPHP},
|
||||||
|
{Name: "jscvt", Feature: &ARM64.HasJSCVT},
|
||||||
|
{Name: "lrcpc", Feature: &ARM64.HasLRCPC},
|
||||||
|
{Name: "pmull", Feature: &ARM64.HasPMULL},
|
||||||
|
{Name: "sha1", Feature: &ARM64.HasSHA1},
|
||||||
|
{Name: "sha2", Feature: &ARM64.HasSHA2},
|
||||||
|
{Name: "sha3", Feature: &ARM64.HasSHA3},
|
||||||
|
{Name: "sha512", Feature: &ARM64.HasSHA512},
|
||||||
|
{Name: "sm3", Feature: &ARM64.HasSM3},
|
||||||
|
{Name: "sm4", Feature: &ARM64.HasSM4},
|
||||||
|
{Name: "sve", Feature: &ARM64.HasSVE},
|
||||||
|
{Name: "crc32", Feature: &ARM64.HasCRC32},
|
||||||
|
{Name: "atomics", Feature: &ARM64.HasATOMICS},
|
||||||
|
{Name: "asimdhp", Feature: &ARM64.HasASIMDHP},
|
||||||
|
{Name: "cpuid", Feature: &ARM64.HasCPUID},
|
||||||
|
{Name: "asimrdm", Feature: &ARM64.HasASIMDRDM},
|
||||||
|
{Name: "fcma", Feature: &ARM64.HasFCMA},
|
||||||
|
{Name: "dcpop", Feature: &ARM64.HasDCPOP},
|
||||||
|
{Name: "asimddp", Feature: &ARM64.HasASIMDDP},
|
||||||
|
{Name: "asimdfhm", Feature: &ARM64.HasASIMDFHM},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func archInit() {
|
||||||
|
switch runtime.GOOS {
|
||||||
|
case "freebsd":
|
||||||
|
readARM64Registers()
|
||||||
|
case "linux", "netbsd":
|
||||||
|
doinit()
|
||||||
|
default:
|
||||||
|
// Most platforms don't seem to allow reading these registers.
|
||||||
|
//
|
||||||
|
// OpenBSD:
|
||||||
|
// See https://golang.org/issue/31746
|
||||||
|
setMinimalFeatures()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// setMinimalFeatures fakes the minimal ARM64 features expected by
|
||||||
|
// TestARM64minimalFeatures.
|
||||||
|
func setMinimalFeatures() {
|
||||||
|
ARM64.HasASIMD = true
|
||||||
|
ARM64.HasFP = true
|
||||||
|
}
|
||||||
|
|
||||||
|
func readARM64Registers() {
|
||||||
|
Initialized = true
|
||||||
|
|
||||||
|
parseARM64SystemRegisters(getisar0(), getisar1(), getpfr0())
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseARM64SystemRegisters(isar0, isar1, pfr0 uint64) {
|
||||||
|
// ID_AA64ISAR0_EL1
|
||||||
|
switch extractBits(isar0, 4, 7) {
|
||||||
|
case 1:
|
||||||
|
ARM64.HasAES = true
|
||||||
|
case 2:
|
||||||
|
ARM64.HasAES = true
|
||||||
|
ARM64.HasPMULL = true
|
||||||
|
}
|
||||||
|
|
||||||
|
switch extractBits(isar0, 8, 11) {
|
||||||
|
case 1:
|
||||||
|
ARM64.HasSHA1 = true
|
||||||
|
}
|
||||||
|
|
||||||
|
switch extractBits(isar0, 12, 15) {
|
||||||
|
case 1:
|
||||||
|
ARM64.HasSHA2 = true
|
||||||
|
case 2:
|
||||||
|
ARM64.HasSHA2 = true
|
||||||
|
ARM64.HasSHA512 = true
|
||||||
|
}
|
||||||
|
|
||||||
|
switch extractBits(isar0, 16, 19) {
|
||||||
|
case 1:
|
||||||
|
ARM64.HasCRC32 = true
|
||||||
|
}
|
||||||
|
|
||||||
|
switch extractBits(isar0, 20, 23) {
|
||||||
|
case 2:
|
||||||
|
ARM64.HasATOMICS = true
|
||||||
|
}
|
||||||
|
|
||||||
|
switch extractBits(isar0, 28, 31) {
|
||||||
|
case 1:
|
||||||
|
ARM64.HasASIMDRDM = true
|
||||||
|
}
|
||||||
|
|
||||||
|
switch extractBits(isar0, 32, 35) {
|
||||||
|
case 1:
|
||||||
|
ARM64.HasSHA3 = true
|
||||||
|
}
|
||||||
|
|
||||||
|
switch extractBits(isar0, 36, 39) {
|
||||||
|
case 1:
|
||||||
|
ARM64.HasSM3 = true
|
||||||
|
}
|
||||||
|
|
||||||
|
switch extractBits(isar0, 40, 43) {
|
||||||
|
case 1:
|
||||||
|
ARM64.HasSM4 = true
|
||||||
|
}
|
||||||
|
|
||||||
|
switch extractBits(isar0, 44, 47) {
|
||||||
|
case 1:
|
||||||
|
ARM64.HasASIMDDP = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// ID_AA64ISAR1_EL1
|
||||||
|
switch extractBits(isar1, 0, 3) {
|
||||||
|
case 1:
|
||||||
|
ARM64.HasDCPOP = true
|
||||||
|
}
|
||||||
|
|
||||||
|
switch extractBits(isar1, 12, 15) {
|
||||||
|
case 1:
|
||||||
|
ARM64.HasJSCVT = true
|
||||||
|
}
|
||||||
|
|
||||||
|
switch extractBits(isar1, 16, 19) {
|
||||||
|
case 1:
|
||||||
|
ARM64.HasFCMA = true
|
||||||
|
}
|
||||||
|
|
||||||
|
switch extractBits(isar1, 20, 23) {
|
||||||
|
case 1:
|
||||||
|
ARM64.HasLRCPC = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// ID_AA64PFR0_EL1
|
||||||
|
switch extractBits(pfr0, 16, 19) {
|
||||||
|
case 0:
|
||||||
|
ARM64.HasFP = true
|
||||||
|
case 1:
|
||||||
|
ARM64.HasFP = true
|
||||||
|
ARM64.HasFPHP = true
|
||||||
|
}
|
||||||
|
|
||||||
|
switch extractBits(pfr0, 20, 23) {
|
||||||
|
case 0:
|
||||||
|
ARM64.HasASIMD = true
|
||||||
|
case 1:
|
||||||
|
ARM64.HasASIMD = true
|
||||||
|
ARM64.HasASIMDHP = true
|
||||||
|
}
|
||||||
|
|
||||||
|
switch extractBits(pfr0, 32, 35) {
|
||||||
|
case 1:
|
||||||
|
ARM64.HasSVE = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func extractBits(data uint64, start, end uint) uint {
|
||||||
|
return (uint)(data>>start) & ((1 << (end - start + 1)) - 1)
|
||||||
|
}
|
31
vendor/golang.org/x/sys/cpu/cpu_arm64.s
generated
vendored
Normal file
31
vendor/golang.org/x/sys/cpu/cpu_arm64.s
generated
vendored
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
// Copyright 2019 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build gc
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
// func getisar0() uint64
|
||||||
|
TEXT ·getisar0(SB),NOSPLIT,$0-8
|
||||||
|
// get Instruction Set Attributes 0 into x0
|
||||||
|
// mrs x0, ID_AA64ISAR0_EL1 = d5380600
|
||||||
|
WORD $0xd5380600
|
||||||
|
MOVD R0, ret+0(FP)
|
||||||
|
RET
|
||||||
|
|
||||||
|
// func getisar1() uint64
|
||||||
|
TEXT ·getisar1(SB),NOSPLIT,$0-8
|
||||||
|
// get Instruction Set Attributes 1 into x0
|
||||||
|
// mrs x0, ID_AA64ISAR1_EL1 = d5380620
|
||||||
|
WORD $0xd5380620
|
||||||
|
MOVD R0, ret+0(FP)
|
||||||
|
RET
|
||||||
|
|
||||||
|
// func getpfr0() uint64
|
||||||
|
TEXT ·getpfr0(SB),NOSPLIT,$0-8
|
||||||
|
// get Processor Feature Register 0 into x0
|
||||||
|
// mrs x0, ID_AA64PFR0_EL1 = d5380400
|
||||||
|
WORD $0xd5380400
|
||||||
|
MOVD R0, ret+0(FP)
|
||||||
|
RET
|
11
vendor/golang.org/x/sys/cpu/cpu_gc_arm64.go
generated
vendored
Normal file
11
vendor/golang.org/x/sys/cpu/cpu_gc_arm64.go
generated
vendored
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// Copyright 2019 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build gc
|
||||||
|
|
||||||
|
package cpu
|
||||||
|
|
||||||
|
func getisar0() uint64
|
||||||
|
func getisar1() uint64
|
||||||
|
func getpfr0() uint64
|
21
vendor/golang.org/x/sys/cpu/cpu_gc_s390x.go
generated
vendored
Normal file
21
vendor/golang.org/x/sys/cpu/cpu_gc_s390x.go
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
// Copyright 2019 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build gc
|
||||||
|
|
||||||
|
package cpu
|
||||||
|
|
||||||
|
// haveAsmFunctions reports whether the other functions in this file can
|
||||||
|
// be safely called.
|
||||||
|
func haveAsmFunctions() bool { return true }
|
||||||
|
|
||||||
|
// The following feature detection functions are defined in cpu_s390x.s.
|
||||||
|
// They are likely to be expensive to call so the results should be cached.
|
||||||
|
func stfle() facilityList
|
||||||
|
func kmQuery() queryResult
|
||||||
|
func kmcQuery() queryResult
|
||||||
|
func kmctrQuery() queryResult
|
||||||
|
func kmaQuery() queryResult
|
||||||
|
func kimdQuery() queryResult
|
||||||
|
func klmdQuery() queryResult
|
16
vendor/golang.org/x/sys/cpu/cpu_gc_x86.go
generated
vendored
Normal file
16
vendor/golang.org/x/sys/cpu/cpu_gc_x86.go
generated
vendored
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build 386 amd64 amd64p32
|
||||||
|
// +build gc
|
||||||
|
|
||||||
|
package cpu
|
||||||
|
|
||||||
|
// cpuid is implemented in cpu_x86.s for gc compiler
|
||||||
|
// and in cpu_gccgo.c for gccgo.
|
||||||
|
func cpuid(eaxArg, ecxArg uint32) (eax, ebx, ecx, edx uint32)
|
||||||
|
|
||||||
|
// xgetbv with ecx = 0 is implemented in cpu_x86.s for gc compiler
|
||||||
|
// and in cpu_gccgo.c for gccgo.
|
||||||
|
func xgetbv() (eax, edx uint32)
|
11
vendor/golang.org/x/sys/cpu/cpu_gccgo_arm64.go
generated
vendored
Normal file
11
vendor/golang.org/x/sys/cpu/cpu_gccgo_arm64.go
generated
vendored
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// Copyright 2019 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build gccgo
|
||||||
|
|
||||||
|
package cpu
|
||||||
|
|
||||||
|
func getisar0() uint64 { return 0 }
|
||||||
|
func getisar1() uint64 { return 0 }
|
||||||
|
func getpfr0() uint64 { return 0 }
|
22
vendor/golang.org/x/sys/cpu/cpu_gccgo_s390x.go
generated
vendored
Normal file
22
vendor/golang.org/x/sys/cpu/cpu_gccgo_s390x.go
generated
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
// Copyright 2019 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build gccgo
|
||||||
|
|
||||||
|
package cpu
|
||||||
|
|
||||||
|
// haveAsmFunctions reports whether the other functions in this file can
|
||||||
|
// be safely called.
|
||||||
|
func haveAsmFunctions() bool { return false }
|
||||||
|
|
||||||
|
// TODO(mundaym): the following feature detection functions are currently
|
||||||
|
// stubs. See https://golang.org/cl/162887 for how to fix this.
|
||||||
|
// They are likely to be expensive to call so the results should be cached.
|
||||||
|
func stfle() facilityList { panic("not implemented for gccgo") }
|
||||||
|
func kmQuery() queryResult { panic("not implemented for gccgo") }
|
||||||
|
func kmcQuery() queryResult { panic("not implemented for gccgo") }
|
||||||
|
func kmctrQuery() queryResult { panic("not implemented for gccgo") }
|
||||||
|
func kmaQuery() queryResult { panic("not implemented for gccgo") }
|
||||||
|
func kimdQuery() queryResult { panic("not implemented for gccgo") }
|
||||||
|
func klmdQuery() queryResult { panic("not implemented for gccgo") }
|
43
vendor/golang.org/x/sys/cpu/cpu_gccgo_x86.c
generated
vendored
Normal file
43
vendor/golang.org/x/sys/cpu/cpu_gccgo_x86.c
generated
vendored
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build 386 amd64 amd64p32
|
||||||
|
// +build gccgo
|
||||||
|
|
||||||
|
#include <cpuid.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
// Need to wrap __get_cpuid_count because it's declared as static.
|
||||||
|
int
|
||||||
|
gccgoGetCpuidCount(uint32_t leaf, uint32_t subleaf,
|
||||||
|
uint32_t *eax, uint32_t *ebx,
|
||||||
|
uint32_t *ecx, uint32_t *edx)
|
||||||
|
{
|
||||||
|
return __get_cpuid_count(leaf, subleaf, eax, ebx, ecx, edx);
|
||||||
|
}
|
||||||
|
|
||||||
|
// xgetbv reads the contents of an XCR (Extended Control Register)
|
||||||
|
// specified in the ECX register into registers EDX:EAX.
|
||||||
|
// Currently, the only supported value for XCR is 0.
|
||||||
|
//
|
||||||
|
// TODO: Replace with a better alternative:
|
||||||
|
//
|
||||||
|
// #include <xsaveintrin.h>
|
||||||
|
//
|
||||||
|
// #pragma GCC target("xsave")
|
||||||
|
//
|
||||||
|
// void gccgoXgetbv(uint32_t *eax, uint32_t *edx) {
|
||||||
|
// unsigned long long x = _xgetbv(0);
|
||||||
|
// *eax = x & 0xffffffff;
|
||||||
|
// *edx = (x >> 32) & 0xffffffff;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// Note that _xgetbv is defined starting with GCC 8.
|
||||||
|
void
|
||||||
|
gccgoXgetbv(uint32_t *eax, uint32_t *edx)
|
||||||
|
{
|
||||||
|
__asm(" xorl %%ecx, %%ecx\n"
|
||||||
|
" xgetbv"
|
||||||
|
: "=a"(*eax), "=d"(*edx));
|
||||||
|
}
|
26
vendor/golang.org/x/sys/cpu/cpu_gccgo_x86.go
generated
vendored
Normal file
26
vendor/golang.org/x/sys/cpu/cpu_gccgo_x86.go
generated
vendored
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build 386 amd64 amd64p32
|
||||||
|
// +build gccgo
|
||||||
|
|
||||||
|
package cpu
|
||||||
|
|
||||||
|
//extern gccgoGetCpuidCount
|
||||||
|
func gccgoGetCpuidCount(eaxArg, ecxArg uint32, eax, ebx, ecx, edx *uint32)
|
||||||
|
|
||||||
|
func cpuid(eaxArg, ecxArg uint32) (eax, ebx, ecx, edx uint32) {
|
||||||
|
var a, b, c, d uint32
|
||||||
|
gccgoGetCpuidCount(eaxArg, ecxArg, &a, &b, &c, &d)
|
||||||
|
return a, b, c, d
|
||||||
|
}
|
||||||
|
|
||||||
|
//extern gccgoXgetbv
|
||||||
|
func gccgoXgetbv(eax, edx *uint32)
|
||||||
|
|
||||||
|
func xgetbv() (eax, edx uint32) {
|
||||||
|
var a, d uint32
|
||||||
|
gccgoXgetbv(&a, &d)
|
||||||
|
return a, d
|
||||||
|
}
|
15
vendor/golang.org/x/sys/cpu/cpu_linux.go
generated
vendored
Normal file
15
vendor/golang.org/x/sys/cpu/cpu_linux.go
generated
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !386,!amd64,!amd64p32,!arm64
|
||||||
|
|
||||||
|
package cpu
|
||||||
|
|
||||||
|
func archInit() {
|
||||||
|
if err := readHWCAP(); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
doinit()
|
||||||
|
Initialized = true
|
||||||
|
}
|
39
vendor/golang.org/x/sys/cpu/cpu_linux_arm.go
generated
vendored
Normal file
39
vendor/golang.org/x/sys/cpu/cpu_linux_arm.go
generated
vendored
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
// Copyright 2019 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package cpu
|
||||||
|
|
||||||
|
func doinit() {
|
||||||
|
ARM.HasSWP = isSet(hwCap, hwcap_SWP)
|
||||||
|
ARM.HasHALF = isSet(hwCap, hwcap_HALF)
|
||||||
|
ARM.HasTHUMB = isSet(hwCap, hwcap_THUMB)
|
||||||
|
ARM.Has26BIT = isSet(hwCap, hwcap_26BIT)
|
||||||
|
ARM.HasFASTMUL = isSet(hwCap, hwcap_FAST_MULT)
|
||||||
|
ARM.HasFPA = isSet(hwCap, hwcap_FPA)
|
||||||
|
ARM.HasVFP = isSet(hwCap, hwcap_VFP)
|
||||||
|
ARM.HasEDSP = isSet(hwCap, hwcap_EDSP)
|
||||||
|
ARM.HasJAVA = isSet(hwCap, hwcap_JAVA)
|
||||||
|
ARM.HasIWMMXT = isSet(hwCap, hwcap_IWMMXT)
|
||||||
|
ARM.HasCRUNCH = isSet(hwCap, hwcap_CRUNCH)
|
||||||
|
ARM.HasTHUMBEE = isSet(hwCap, hwcap_THUMBEE)
|
||||||
|
ARM.HasNEON = isSet(hwCap, hwcap_NEON)
|
||||||
|
ARM.HasVFPv3 = isSet(hwCap, hwcap_VFPv3)
|
||||||
|
ARM.HasVFPv3D16 = isSet(hwCap, hwcap_VFPv3D16)
|
||||||
|
ARM.HasTLS = isSet(hwCap, hwcap_TLS)
|
||||||
|
ARM.HasVFPv4 = isSet(hwCap, hwcap_VFPv4)
|
||||||
|
ARM.HasIDIVA = isSet(hwCap, hwcap_IDIVA)
|
||||||
|
ARM.HasIDIVT = isSet(hwCap, hwcap_IDIVT)
|
||||||
|
ARM.HasVFPD32 = isSet(hwCap, hwcap_VFPD32)
|
||||||
|
ARM.HasLPAE = isSet(hwCap, hwcap_LPAE)
|
||||||
|
ARM.HasEVTSTRM = isSet(hwCap, hwcap_EVTSTRM)
|
||||||
|
ARM.HasAES = isSet(hwCap2, hwcap2_AES)
|
||||||
|
ARM.HasPMULL = isSet(hwCap2, hwcap2_PMULL)
|
||||||
|
ARM.HasSHA1 = isSet(hwCap2, hwcap2_SHA1)
|
||||||
|
ARM.HasSHA2 = isSet(hwCap2, hwcap2_SHA2)
|
||||||
|
ARM.HasCRC32 = isSet(hwCap2, hwcap2_CRC32)
|
||||||
|
}
|
||||||
|
|
||||||
|
func isSet(hwc uint, value uint) bool {
|
||||||
|
return hwc&value != 0
|
||||||
|
}
|
71
vendor/golang.org/x/sys/cpu/cpu_linux_arm64.go
generated
vendored
Normal file
71
vendor/golang.org/x/sys/cpu/cpu_linux_arm64.go
generated
vendored
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package cpu
|
||||||
|
|
||||||
|
// HWCAP/HWCAP2 bits. These are exposed by Linux.
|
||||||
|
const (
|
||||||
|
hwcap_FP = 1 << 0
|
||||||
|
hwcap_ASIMD = 1 << 1
|
||||||
|
hwcap_EVTSTRM = 1 << 2
|
||||||
|
hwcap_AES = 1 << 3
|
||||||
|
hwcap_PMULL = 1 << 4
|
||||||
|
hwcap_SHA1 = 1 << 5
|
||||||
|
hwcap_SHA2 = 1 << 6
|
||||||
|
hwcap_CRC32 = 1 << 7
|
||||||
|
hwcap_ATOMICS = 1 << 8
|
||||||
|
hwcap_FPHP = 1 << 9
|
||||||
|
hwcap_ASIMDHP = 1 << 10
|
||||||
|
hwcap_CPUID = 1 << 11
|
||||||
|
hwcap_ASIMDRDM = 1 << 12
|
||||||
|
hwcap_JSCVT = 1 << 13
|
||||||
|
hwcap_FCMA = 1 << 14
|
||||||
|
hwcap_LRCPC = 1 << 15
|
||||||
|
hwcap_DCPOP = 1 << 16
|
||||||
|
hwcap_SHA3 = 1 << 17
|
||||||
|
hwcap_SM3 = 1 << 18
|
||||||
|
hwcap_SM4 = 1 << 19
|
||||||
|
hwcap_ASIMDDP = 1 << 20
|
||||||
|
hwcap_SHA512 = 1 << 21
|
||||||
|
hwcap_SVE = 1 << 22
|
||||||
|
hwcap_ASIMDFHM = 1 << 23
|
||||||
|
)
|
||||||
|
|
||||||
|
func doinit() {
|
||||||
|
if err := readHWCAP(); err != nil {
|
||||||
|
// failed to read /proc/self/auxv, try reading registers directly
|
||||||
|
readARM64Registers()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// HWCAP feature bits
|
||||||
|
ARM64.HasFP = isSet(hwCap, hwcap_FP)
|
||||||
|
ARM64.HasASIMD = isSet(hwCap, hwcap_ASIMD)
|
||||||
|
ARM64.HasEVTSTRM = isSet(hwCap, hwcap_EVTSTRM)
|
||||||
|
ARM64.HasAES = isSet(hwCap, hwcap_AES)
|
||||||
|
ARM64.HasPMULL = isSet(hwCap, hwcap_PMULL)
|
||||||
|
ARM64.HasSHA1 = isSet(hwCap, hwcap_SHA1)
|
||||||
|
ARM64.HasSHA2 = isSet(hwCap, hwcap_SHA2)
|
||||||
|
ARM64.HasCRC32 = isSet(hwCap, hwcap_CRC32)
|
||||||
|
ARM64.HasATOMICS = isSet(hwCap, hwcap_ATOMICS)
|
||||||
|
ARM64.HasFPHP = isSet(hwCap, hwcap_FPHP)
|
||||||
|
ARM64.HasASIMDHP = isSet(hwCap, hwcap_ASIMDHP)
|
||||||
|
ARM64.HasCPUID = isSet(hwCap, hwcap_CPUID)
|
||||||
|
ARM64.HasASIMDRDM = isSet(hwCap, hwcap_ASIMDRDM)
|
||||||
|
ARM64.HasJSCVT = isSet(hwCap, hwcap_JSCVT)
|
||||||
|
ARM64.HasFCMA = isSet(hwCap, hwcap_FCMA)
|
||||||
|
ARM64.HasLRCPC = isSet(hwCap, hwcap_LRCPC)
|
||||||
|
ARM64.HasDCPOP = isSet(hwCap, hwcap_DCPOP)
|
||||||
|
ARM64.HasSHA3 = isSet(hwCap, hwcap_SHA3)
|
||||||
|
ARM64.HasSM3 = isSet(hwCap, hwcap_SM3)
|
||||||
|
ARM64.HasSM4 = isSet(hwCap, hwcap_SM4)
|
||||||
|
ARM64.HasASIMDDP = isSet(hwCap, hwcap_ASIMDDP)
|
||||||
|
ARM64.HasSHA512 = isSet(hwCap, hwcap_SHA512)
|
||||||
|
ARM64.HasSVE = isSet(hwCap, hwcap_SVE)
|
||||||
|
ARM64.HasASIMDFHM = isSet(hwCap, hwcap_ASIMDFHM)
|
||||||
|
}
|
||||||
|
|
||||||
|
func isSet(hwc uint, value uint) bool {
|
||||||
|
return hwc&value != 0
|
||||||
|
}
|
23
vendor/golang.org/x/sys/cpu/cpu_linux_mips64x.go
generated
vendored
Normal file
23
vendor/golang.org/x/sys/cpu/cpu_linux_mips64x.go
generated
vendored
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
// Copyright 2020 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build linux
|
||||||
|
// +build mips64 mips64le
|
||||||
|
|
||||||
|
package cpu
|
||||||
|
|
||||||
|
// HWCAP bits. These are exposed by the Linux kernel 5.4.
|
||||||
|
const (
|
||||||
|
// CPU features
|
||||||
|
hwcap_MIPS_MSA = 1 << 1
|
||||||
|
)
|
||||||
|
|
||||||
|
func doinit() {
|
||||||
|
// HWCAP feature bits
|
||||||
|
MIPS64X.HasMSA = isSet(hwCap, hwcap_MIPS_MSA)
|
||||||
|
}
|
||||||
|
|
||||||
|
func isSet(hwc uint, value uint) bool {
|
||||||
|
return hwc&value != 0
|
||||||
|
}
|
9
vendor/golang.org/x/sys/cpu/cpu_linux_noinit.go
generated
vendored
Normal file
9
vendor/golang.org/x/sys/cpu/cpu_linux_noinit.go
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
// Copyright 2019 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build linux,!arm,!arm64,!mips64,!mips64le,!ppc64,!ppc64le,!s390x
|
||||||
|
|
||||||
|
package cpu
|
||||||
|
|
||||||
|
func doinit() {}
|
31
vendor/golang.org/x/sys/cpu/cpu_linux_ppc64x.go
generated
vendored
Normal file
31
vendor/golang.org/x/sys/cpu/cpu_linux_ppc64x.go
generated
vendored
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build linux
|
||||||
|
// +build ppc64 ppc64le
|
||||||
|
|
||||||
|
package cpu
|
||||||
|
|
||||||
|
// HWCAP/HWCAP2 bits. These are exposed by the kernel.
|
||||||
|
const (
|
||||||
|
// ISA Level
|
||||||
|
_PPC_FEATURE2_ARCH_2_07 = 0x80000000
|
||||||
|
_PPC_FEATURE2_ARCH_3_00 = 0x00800000
|
||||||
|
|
||||||
|
// CPU features
|
||||||
|
_PPC_FEATURE2_DARN = 0x00200000
|
||||||
|
_PPC_FEATURE2_SCV = 0x00100000
|
||||||
|
)
|
||||||
|
|
||||||
|
func doinit() {
|
||||||
|
// HWCAP2 feature bits
|
||||||
|
PPC64.IsPOWER8 = isSet(hwCap2, _PPC_FEATURE2_ARCH_2_07)
|
||||||
|
PPC64.IsPOWER9 = isSet(hwCap2, _PPC_FEATURE2_ARCH_3_00)
|
||||||
|
PPC64.HasDARN = isSet(hwCap2, _PPC_FEATURE2_DARN)
|
||||||
|
PPC64.HasSCV = isSet(hwCap2, _PPC_FEATURE2_SCV)
|
||||||
|
}
|
||||||
|
|
||||||
|
func isSet(hwc uint, value uint) bool {
|
||||||
|
return hwc&value != 0
|
||||||
|
}
|
40
vendor/golang.org/x/sys/cpu/cpu_linux_s390x.go
generated
vendored
Normal file
40
vendor/golang.org/x/sys/cpu/cpu_linux_s390x.go
generated
vendored
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
// Copyright 2019 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package cpu
|
||||||
|
|
||||||
|
const (
|
||||||
|
// bit mask values from /usr/include/bits/hwcap.h
|
||||||
|
hwcap_ZARCH = 2
|
||||||
|
hwcap_STFLE = 4
|
||||||
|
hwcap_MSA = 8
|
||||||
|
hwcap_LDISP = 16
|
||||||
|
hwcap_EIMM = 32
|
||||||
|
hwcap_DFP = 64
|
||||||
|
hwcap_ETF3EH = 256
|
||||||
|
hwcap_VX = 2048
|
||||||
|
hwcap_VXE = 8192
|
||||||
|
)
|
||||||
|
|
||||||
|
func initS390Xbase() {
|
||||||
|
// test HWCAP bit vector
|
||||||
|
has := func(featureMask uint) bool {
|
||||||
|
return hwCap&featureMask == featureMask
|
||||||
|
}
|
||||||
|
|
||||||
|
// mandatory
|
||||||
|
S390X.HasZARCH = has(hwcap_ZARCH)
|
||||||
|
|
||||||
|
// optional
|
||||||
|
S390X.HasSTFLE = has(hwcap_STFLE)
|
||||||
|
S390X.HasLDISP = has(hwcap_LDISP)
|
||||||
|
S390X.HasEIMM = has(hwcap_EIMM)
|
||||||
|
S390X.HasETF3EH = has(hwcap_ETF3EH)
|
||||||
|
S390X.HasDFP = has(hwcap_DFP)
|
||||||
|
S390X.HasMSA = has(hwcap_MSA)
|
||||||
|
S390X.HasVX = has(hwcap_VX)
|
||||||
|
if S390X.HasVX {
|
||||||
|
S390X.HasVXE = has(hwcap_VXE)
|
||||||
|
}
|
||||||
|
}
|
15
vendor/golang.org/x/sys/cpu/cpu_mips64x.go
generated
vendored
Normal file
15
vendor/golang.org/x/sys/cpu/cpu_mips64x.go
generated
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build mips64 mips64le
|
||||||
|
|
||||||
|
package cpu
|
||||||
|
|
||||||
|
const cacheLineSize = 32
|
||||||
|
|
||||||
|
func initOptions() {
|
||||||
|
options = []option{
|
||||||
|
{Name: "msa", Feature: &MIPS64X.HasMSA},
|
||||||
|
}
|
||||||
|
}
|
11
vendor/golang.org/x/sys/cpu/cpu_mipsx.go
generated
vendored
Normal file
11
vendor/golang.org/x/sys/cpu/cpu_mipsx.go
generated
vendored
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build mips mipsle
|
||||||
|
|
||||||
|
package cpu
|
||||||
|
|
||||||
|
const cacheLineSize = 32
|
||||||
|
|
||||||
|
func initOptions() {}
|
173
vendor/golang.org/x/sys/cpu/cpu_netbsd_arm64.go
generated
vendored
Normal file
173
vendor/golang.org/x/sys/cpu/cpu_netbsd_arm64.go
generated
vendored
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
// Copyright 2020 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package cpu
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Minimal copy of functionality from x/sys/unix so the cpu package can call
|
||||||
|
// sysctl without depending on x/sys/unix.
|
||||||
|
|
||||||
|
const (
|
||||||
|
_CTL_QUERY = -2
|
||||||
|
|
||||||
|
_SYSCTL_VERS_1 = 0x1000000
|
||||||
|
)
|
||||||
|
|
||||||
|
var _zero uintptr
|
||||||
|
|
||||||
|
func sysctl(mib []int32, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) {
|
||||||
|
var _p0 unsafe.Pointer
|
||||||
|
if len(mib) > 0 {
|
||||||
|
_p0 = unsafe.Pointer(&mib[0])
|
||||||
|
} else {
|
||||||
|
_p0 = unsafe.Pointer(&_zero)
|
||||||
|
}
|
||||||
|
_, _, errno := syscall.Syscall6(
|
||||||
|
syscall.SYS___SYSCTL,
|
||||||
|
uintptr(_p0),
|
||||||
|
uintptr(len(mib)),
|
||||||
|
uintptr(unsafe.Pointer(old)),
|
||||||
|
uintptr(unsafe.Pointer(oldlen)),
|
||||||
|
uintptr(unsafe.Pointer(new)),
|
||||||
|
uintptr(newlen))
|
||||||
|
if errno != 0 {
|
||||||
|
return errno
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type sysctlNode struct {
|
||||||
|
Flags uint32
|
||||||
|
Num int32
|
||||||
|
Name [32]int8
|
||||||
|
Ver uint32
|
||||||
|
__rsvd uint32
|
||||||
|
Un [16]byte
|
||||||
|
_sysctl_size [8]byte
|
||||||
|
_sysctl_func [8]byte
|
||||||
|
_sysctl_parent [8]byte
|
||||||
|
_sysctl_desc [8]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func sysctlNodes(mib []int32) ([]sysctlNode, error) {
|
||||||
|
var olen uintptr
|
||||||
|
|
||||||
|
// Get a list of all sysctl nodes below the given MIB by performing
|
||||||
|
// a sysctl for the given MIB with CTL_QUERY appended.
|
||||||
|
mib = append(mib, _CTL_QUERY)
|
||||||
|
qnode := sysctlNode{Flags: _SYSCTL_VERS_1}
|
||||||
|
qp := (*byte)(unsafe.Pointer(&qnode))
|
||||||
|
sz := unsafe.Sizeof(qnode)
|
||||||
|
if err := sysctl(mib, nil, &olen, qp, sz); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now that we know the size, get the actual nodes.
|
||||||
|
nodes := make([]sysctlNode, olen/sz)
|
||||||
|
np := (*byte)(unsafe.Pointer(&nodes[0]))
|
||||||
|
if err := sysctl(mib, np, &olen, qp, sz); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nodes, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func nametomib(name string) ([]int32, error) {
|
||||||
|
// Split name into components.
|
||||||
|
var parts []string
|
||||||
|
last := 0
|
||||||
|
for i := 0; i < len(name); i++ {
|
||||||
|
if name[i] == '.' {
|
||||||
|
parts = append(parts, name[last:i])
|
||||||
|
last = i + 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
parts = append(parts, name[last:])
|
||||||
|
|
||||||
|
mib := []int32{}
|
||||||
|
// Discover the nodes and construct the MIB OID.
|
||||||
|
for partno, part := range parts {
|
||||||
|
nodes, err := sysctlNodes(mib)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, node := range nodes {
|
||||||
|
n := make([]byte, 0)
|
||||||
|
for i := range node.Name {
|
||||||
|
if node.Name[i] != 0 {
|
||||||
|
n = append(n, byte(node.Name[i]))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if string(n) == part {
|
||||||
|
mib = append(mib, int32(node.Num))
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(mib) != partno+1 {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mib, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// aarch64SysctlCPUID is struct aarch64_sysctl_cpu_id from NetBSD's <aarch64/armreg.h>
|
||||||
|
type aarch64SysctlCPUID struct {
|
||||||
|
midr uint64 /* Main ID Register */
|
||||||
|
revidr uint64 /* Revision ID Register */
|
||||||
|
mpidr uint64 /* Multiprocessor Affinity Register */
|
||||||
|
aa64dfr0 uint64 /* A64 Debug Feature Register 0 */
|
||||||
|
aa64dfr1 uint64 /* A64 Debug Feature Register 1 */
|
||||||
|
aa64isar0 uint64 /* A64 Instruction Set Attribute Register 0 */
|
||||||
|
aa64isar1 uint64 /* A64 Instruction Set Attribute Register 1 */
|
||||||
|
aa64mmfr0 uint64 /* A64 Memory Model Feature Register 0 */
|
||||||
|
aa64mmfr1 uint64 /* A64 Memory Model Feature Register 1 */
|
||||||
|
aa64mmfr2 uint64 /* A64 Memory Model Feature Register 2 */
|
||||||
|
aa64pfr0 uint64 /* A64 Processor Feature Register 0 */
|
||||||
|
aa64pfr1 uint64 /* A64 Processor Feature Register 1 */
|
||||||
|
aa64zfr0 uint64 /* A64 SVE Feature ID Register 0 */
|
||||||
|
mvfr0 uint32 /* Media and VFP Feature Register 0 */
|
||||||
|
mvfr1 uint32 /* Media and VFP Feature Register 1 */
|
||||||
|
mvfr2 uint32 /* Media and VFP Feature Register 2 */
|
||||||
|
pad uint32
|
||||||
|
clidr uint64 /* Cache Level ID Register */
|
||||||
|
ctr uint64 /* Cache Type Register */
|
||||||
|
}
|
||||||
|
|
||||||
|
func sysctlCPUID(name string) (*aarch64SysctlCPUID, error) {
|
||||||
|
mib, err := nametomib(name)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
out := aarch64SysctlCPUID{}
|
||||||
|
n := unsafe.Sizeof(out)
|
||||||
|
_, _, errno := syscall.Syscall6(
|
||||||
|
syscall.SYS___SYSCTL,
|
||||||
|
uintptr(unsafe.Pointer(&mib[0])),
|
||||||
|
uintptr(len(mib)),
|
||||||
|
uintptr(unsafe.Pointer(&out)),
|
||||||
|
uintptr(unsafe.Pointer(&n)),
|
||||||
|
uintptr(0),
|
||||||
|
uintptr(0))
|
||||||
|
if errno != 0 {
|
||||||
|
return nil, errno
|
||||||
|
}
|
||||||
|
return &out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func doinit() {
|
||||||
|
cpuid, err := sysctlCPUID("machdep.cpu0.cpu_id")
|
||||||
|
if err != nil {
|
||||||
|
setMinimalFeatures()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
parseARM64SystemRegisters(cpuid.aa64isar0, cpuid.aa64isar1, cpuid.aa64pfr0)
|
||||||
|
|
||||||
|
Initialized = true
|
||||||
|
}
|
9
vendor/golang.org/x/sys/cpu/cpu_other_arm.go
generated
vendored
Normal file
9
vendor/golang.org/x/sys/cpu/cpu_other_arm.go
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
// Copyright 2020 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !linux,arm
|
||||||
|
|
||||||
|
package cpu
|
||||||
|
|
||||||
|
func archInit() {}
|
10
vendor/golang.org/x/sys/cpu/cpu_other_arm64.go
generated
vendored
Normal file
10
vendor/golang.org/x/sys/cpu/cpu_other_arm64.go
generated
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
// Copyright 2019 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !linux,!netbsd
|
||||||
|
// +build arm64
|
||||||
|
|
||||||
|
package cpu
|
||||||
|
|
||||||
|
func doinit() {}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user