diff --git a/go.mod b/go.mod index 14b5db30..c490ef16 100644 --- a/go.mod +++ b/go.mod @@ -6,15 +6,17 @@ require ( github.com/fxamacker/cbor/v2 v2.4.0 github.com/go-webauthn/revoke v0.1.3 github.com/golang-jwt/jwt/v4 v4.4.2 + github.com/google/go-tpm v0.3.3 github.com/google/uuid v1.3.0 github.com/mitchellh/mapstructure v1.5.0 github.com/stretchr/testify v1.8.0 - golang.org/x/crypto d6f0a8c073c2 + golang.org/x/crypto v0.0.0-20220817201139-bc19a97f63c8 ) require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/x448/float16 v0.8.4 // indirect + golang.org/x/sys v0.0.0-20210629170331-7dc0b73dc9fb // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 077991be..c09d4da8 100644 --- a/go.sum +++ b/go.sum @@ -1,29 +1,205 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fxamacker/cbor/v2 v2.4.0 h1:ri0ArlOR+5XunOP8CRUowT0pSJOwhW098ZCUyskZD88= github.com/fxamacker/cbor/v2 v2.4.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-webauthn/revoke v0.1.3 h1:SU+/fD+Py4MMTqKnMfBJ5Td4skcvfWtjQbZnvT9ppB0= github.com/go-webauthn/revoke v0.1.3/go.mod h1:Vzr3vqXqGQVS21hYpbetmpIoN4HiSjv2gcZI7ltlneI= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/golang-jwt/jwt/v4 v4.4.2 h1:rcc4lwaZgFMCZ5jxF9ABolDcIHdBytAFgqFPbSJQAYs= github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-tpm v0.1.2-0.20190725015402-ae6dd98980d4/go.mod h1:H9HbmUG2YgV/PHITkO7p6wxEEj/v5nlsVWIwumwH2NI= +github.com/google/go-tpm v0.3.0/go.mod h1:iVLWvrPp/bHeEkxTFi9WG6K9w0iy2yIszHwZGHPbzAw= +github.com/google/go-tpm v0.3.3 h1:P/ZFNBZYXRxc+z7i5uyd8VP7MaDteuLZInzrH2idRGo= +github.com/google/go-tpm v0.3.3/go.mod h1:9Hyn3rgnzWF9XBWVk6ml6A6hNkbWjNFlDQL51BeghL4= +github.com/google/go-tpm-tools v0.0.0-20190906225433-1614c142f845/go.mod h1:AVfHadzbdzHo54inR2x1v640jdi1YSi3NauM2DUsxk0= +github.com/google/go-tpm-tools v0.2.0/go.mod h1:npUd03rQ60lxN7tzeBJreG38RvWwme2N1reF/eeiBk4= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 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/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= +github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= -golang.org/x/crypto v0.0.0-20221005025214-4161e89ecf1b h1:huxqepDufQpLLIRXiVkTvnxrzJlpwmIWAObmcCcUFr0= -golang.org/x/crypto v0.0.0-20221005025214-4161e89ecf1b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20220817201139-bc19a97f63c8 h1:GIAS/yBem/gq2MUqgNIzUHW7cJMmx3TGZOrnyYaNQ6c= +golang.org/x/crypto v0.0.0-20220817201139-bc19a97f63c8/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/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-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/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-20210629170331-7dc0b73dc9fb h1:sgcyLNYiHqEd8eFVh0PflG5ABPTGcPSJacD3s19RTcY= +golang.org/x/sys v0.0.0-20210629170331-7dc0b73dc9fb/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/protocol/attestation_tpm.go b/protocol/attestation_tpm.go index 90f9532b..e5e9afe1 100644 --- a/protocol/attestation_tpm.go +++ b/protocol/attestation_tpm.go @@ -7,20 +7,17 @@ import ( "encoding/asn1" "errors" "fmt" - "math/big" "strings" "github.com/go-webauthn/webauthn/metadata" "github.com/go-webauthn/webauthn/protocol/webauthncose" - - "github.com/go-webauthn/webauthn/protocol/googletpm" + "github.com/google/go-tpm/tpm2" ) var tpmAttestationKey = "tpm" func init() { RegisterAttestationFormat(tpmAttestationKey, verifyTPMFormat) - googletpm.UseTPM20LengthPrefixSize() } func verifyTPMFormat(att AttestationObject, clientDataHash []byte) (string, []interface{}, error) { @@ -74,27 +71,26 @@ func verifyTPMFormat(att AttestationObject, clientDataHash []byte) (string, []in // Verify that the public key specified by the parameters and unique fields of pubArea // is identical to the credentialPublicKey in the attestedCredentialData in authenticatorData. - pubArea, err := googletpm.DecodePublic(pubAreaBytes) + pubArea, err := tpm2.DecodePublic(pubAreaBytes) if err != nil { return "", nil, ErrAttestationFormat.WithDetails("Unable to decode TPMT_PUBLIC in attestation statement") } key, err := webauthncose.ParsePublicKey(att.AuthData.AttData.CredentialPublicKey) if err != nil { - return tpmAttestationKey, nil, err + return "", nil, err } switch key := key.(type) { case webauthncose.EC2PublicKeyData: if pubArea.ECCParameters.CurveID != key.TPMCurveID() || - pubArea.ECCParameters.Point.X.Cmp(new(big.Int).SetBytes(key.XCoord)) != 0 || - pubArea.ECCParameters.Point.Y.Cmp(new(big.Int).SetBytes(key.YCoord)) != 0 { - return tpmAttestationKey, nil, ErrAttestationFormat.WithDetails("Mismatch between ECCParameters in pubArea and credentialPublicKey") + !bytes.Equal(pubArea.ECCParameters.Point.XRaw, key.XCoord) || + !bytes.Equal(pubArea.ECCParameters.Point.YRaw, key.YCoord) { + return "", nil, ErrAttestationFormat.WithDetails("Mismatch between ECCParameters in pubArea and credentialPublicKey") } case webauthncose.RSAPublicKeyData: - mod := new(big.Int).SetBytes(key.Modulus) exp := uint32(key.Exponent[0]) + uint32(key.Exponent[1])<<8 + uint32(key.Exponent[2])<<16 - if pubArea.RSAParameters.Modulus.Cmp(mod) != 0 || - pubArea.RSAParameters.Exponent != exp { + if !bytes.Equal(pubArea.RSAParameters.ModulusRaw, key.Modulus) || + pubArea.RSAParameters.Exponent() != exp { return "", nil, ErrAttestationFormat.WithDetails("Mismatch between RSAParameters in pubArea and credentialPublicKey") } default: @@ -105,16 +101,14 @@ func verifyTPMFormat(att AttestationObject, clientDataHash []byte) (string, []in attToBeSigned := append(att.RawAuthData, clientDataHash...) // Validate that certInfo is valid: - certInfo, err := googletpm.DecodeAttestationData(certInfoBytes) + // 1/4 Verify that magic is set to TPM_GENERATED_VALUE, handled here + certInfo, err := tpm2.DecodeAttestationData(certInfoBytes) if err != nil { - return tpmAttestationKey, nil, err - } - // 1/4 Verify that magic is set to TPM_GENERATED_VALUE. - if certInfo.Magic != 0xff544347 { - return "", nil, ErrAttestationFormat.WithDetails("Magic is not set to TPM_GENERATED_VALUE") + return "", nil, err } + // 2/4 Verify that type is set to TPM_ST_ATTEST_CERTIFY. - if certInfo.Type != googletpm.TagAttestCertify { + if certInfo.Type != tpm2.TagAttestCertify { return "", nil, ErrAttestationFormat.WithDetails("Type is not set to TPM_ST_ATTEST_CERTIFY") } // 3/4 Verify that extraData is set to the hash of attToBeSigned using the hash algorithm employed in "alg". @@ -122,17 +116,19 @@ func verifyTPMFormat(att AttestationObject, clientDataHash []byte) (string, []in h := f() h.Write(attToBeSigned) if !bytes.Equal(certInfo.ExtraData, h.Sum(nil)) { - return tpmAttestationKey, nil, ErrAttestationFormat.WithDetails("ExtraData is not set to hash of attToBeSigned") + return "", nil, ErrAttestationFormat.WithDetails("ExtraData is not set to hash of attToBeSigned") } // 4/4 Verify that attested contains a TPMS_CERTIFY_INFO structure as specified in // [TPMv2-Part2] section 10.12.3, whose name field contains a valid Name for pubArea, // as computed using the algorithm in the nameAlg field of pubArea // using the procedure specified in [TPMv2-Part1] section 16. - f, err = certInfo.AttestedCertifyInfo.Name.Digest.Alg.HashConstructor() - h = f() - h.Write(pubAreaBytes) - if !bytes.Equal(h.Sum(nil), certInfo.AttestedCertifyInfo.Name.Digest.Value) { - return tpmAttestationKey, nil, ErrAttestationFormat.WithDetails("Hash value mismatch attested and pubArea") + matches, err := certInfo.AttestedCertifyInfo.Name.MatchesPublic(pubArea) + if err != nil { + return "", nil, err + } + + if !matches { + return "", nil, ErrAttestationFormat.WithDetails("Hash value mismatch attested and pubArea") } // Note that the remaining fields in the "Standard Attestation Structure" @@ -176,7 +172,7 @@ func verifyTPMFormat(att AttestationObject, clientDataHash []byte) (string, []in if ext.Id.Equal([]int{2, 5, 29, 17}) { manufacturer, model, version, err = parseSANExtension(ext.Value) if err != nil { - return tpmAttestationKey, nil, err + return "", nil, err } } } @@ -186,7 +182,7 @@ func verifyTPMFormat(att AttestationObject, clientDataHash []byte) (string, []in } if !isValidTPMManufacturer(manufacturer) { - return tpmAttestationKey, nil, ErrAttestationFormat.WithDetails("Invalid TPM manufacturer") + return "", nil, ErrAttestationFormat.WithDetails("Invalid TPM manufacturer") } // 4/6 The Extended Key Usage extension MUST contain the "joint-iso-itu-t(2) internationalorganizations(23) 133 tcg-kp(8) tcg-kp-AIKCertificate(3)" OID. @@ -202,7 +198,7 @@ func verifyTPMFormat(att AttestationObject, clientDataHash []byte) (string, []in } } if !ekuValid { - return tpmAttestationKey, nil, ErrAttestationFormat.WithDetails("AIK certificate missing EKU") + return "", nil, ErrAttestationFormat.WithDetails("AIK certificate missing EKU") } // 5/6 The Basic Constraints extension MUST have the CA component set to false. @@ -221,7 +217,7 @@ func verifyTPMFormat(att AttestationObject, clientDataHash []byte) (string, []in } } if constraints.IsCA { - return tpmAttestationKey, nil, ErrAttestationFormat.WithDetails("AIK certificate basic constraints missing or CA is true") + return "", nil, ErrAttestationFormat.WithDetails("AIK certificate basic constraints missing or CA is true") } // 6/6 An Authority Information Access (AIA) extension with entry id-ad-ocsp and a CRL Distribution Point // extension [RFC5280] are both OPTIONAL as the status of many attestation certificates is available diff --git a/protocol/attestation_tpm_test.go b/protocol/attestation_tpm_test.go index 55d9c43f..d537fbee 100644 --- a/protocol/attestation_tpm_test.go +++ b/protocol/attestation_tpm_test.go @@ -1,10 +1,22 @@ package protocol import ( + "crypto/ecdsa" + "crypto/ed25519" + "crypto/elliptic" + "crypto/rand" + "crypto/rsa" "crypto/sha256" + "crypto/x509" + "crypto/x509/pkix" + "encoding/asn1" + "encoding/binary" + "math/big" "testing" - "github.com/go-webauthn/webauthn/protocol/googletpm" + "github.com/go-webauthn/webauthn/protocol/webauthncbor" + "github.com/go-webauthn/webauthn/protocol/webauthncose" + "github.com/google/go-tpm/tpm2" "github.com/stretchr/testify/assert" ) @@ -14,11 +26,11 @@ func TestTPMAttestationVerificationSuccess(t *testing.T) { pcc := attestationTestUnpackResponse(t, testAttestationTPMResponses[i]) clientDataHash := sha256.Sum256(pcc.Raw.AttestationResponse.ClientDataJSON) - attestationKey, _, err := verifyTPMFormat(pcc.Response.AttestationObject, clientDataHash[:]) + attestationType, _, err := verifyTPMFormat(pcc.Response.AttestationObject, clientDataHash[:]) if err != nil { t.Fatalf("Not valid: %+v", err) } - assert.Equal(t, "attca", attestationKey) + assert.Equal(t, "attca", attestationType) }) } } @@ -33,7 +45,7 @@ var testAttestationTPMResponses = []string{ "attestationObject": "o2NmbXRjdHBtZ2F0dFN0bXSmY2FsZzn__mNzaWdZAQCqAcGoi2IFXCF5xxokjR5yOAwK_11iCOqt8hCkpHE9rW602J3KjhcRQzoFf1UxZvadwmYcHHMxDQDmVuOhH-yW-DfARVT7O3MzlhhzrGTNO_-jhGFsGeEdz0RgNsviDdaVP5lNsV6Pe4bMhgBv1aTkk0zx1T8sxK8B7gKT6x80RIWg89_aYY4gHR4n65SRDp2gOGI2IHDvqTwidyeaAHVPbDrF8iDbQ88O-GH_fheAtFtgjbIq-XQbwVdzQhYdWyL0XVUwGLSSuABuB4seRPkyZCKoOU6VuuQzfWNpH2Nl05ybdXi27HysUexgfPxihB3PbR8LJdi1j04tRg3JvBUvY3ZlcmMyLjBjeDVjglkFuzCCBbcwggOfoAMCAQICEGEZiaSlAkKpqaQOKDYmWPkwDQYJKoZIhvcNAQELBQAwQTE_MD0GA1UEAxM2RVVTLU5UQy1LRVlJRC1FNEE4NjY2RjhGNEM2RDlDMzkzMkE5NDg4NDc3ODBBNjgxMEM0MjEzMB4XDTIyMDExMjIyMTUxOFoXDTI3MDYxMDE4NTQzNlowADCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKo-7DHdiipZTzfA9fpTaIMVK887zM0nXAVIvU0kmGAsPpTYbf7dn1DAl6BhcDkXs2WrwYP02K8RxXWOF4jf7esMAIkr65zPWqLys8WRNM60d7g9GOADwbN8qrY0hepSsaJwjhswbNJI6L8vJwnnrQ6UWVCm3xHqn8CB2iSWNSUnshgTQTkJ1ZEdToeD51sFXUE0fSxXjyIiSAAD4tCIZkmHFVqchzfqUgiiM_mbbKzUnxEZ6c6r39ccHzbm4Ir-u62repQnVXKTpzFBbJ-Eg15REvw6xuYaGtpItk27AXVcEodfAylf7pgQPfExWkoMZfb8faqbQAj5x29mBJvlzj0CAwEAAaOCAeowggHmMA4GA1UdDwEB_wQEAwIHgDAMBgNVHRMBAf8EAjAAMG0GA1UdIAEB_wRjMGEwXwYJKwYBBAGCNxUfMFIwUAYIKwYBBQUHAgIwRB5CAFQAQwBQAEEAIAAgAFQAcgB1AHMAdABlAGQAIAAgAFAAbABhAHQAZgBvAHIAbQAgACAASQBkAGUAbgB0AGkAdAB5MBAGA1UdJQQJMAcGBWeBBQgDMFAGA1UdEQEB_wRGMESkQjBAMT4wEAYFZ4EFAgIMB05QQ1Q3NXgwFAYFZ4EFAgEMC2lkOjRFNTQ0MzAwMBQGBWeBBQIDDAtpZDowMDA3MDAwMjAfBgNVHSMEGDAWgBQ3yjAtSXrnaSNOtzy1PEXxOO1ZUDAdBgNVHQ4EFgQU1ml3H5Tzrs0Nev69tFNhPZnhaV0wgbIGCCsGAQUFBwEBBIGlMIGiMIGfBggrBgEFBQcwAoaBkmh0dHA6Ly9hemNzcHJvZGV1c2Fpa3B1Ymxpc2guYmxvYi5jb3JlLndpbmRvd3MubmV0L2V1cy1udGMta2V5aWQtZTRhODY2NmY4ZjRjNmQ5YzM5MzJhOTQ4ODQ3NzgwYTY4MTBjNDIxMy9lMDFjMjA2Mi1mYmRjLTQwYTUtYTQwZi1jMzc3YzBmNzY1MWMuY2VyMA0GCSqGSIb3DQEBCwUAA4ICAQAz-YGrj0S841gyMZuit-qsKpKNdxbkaEhyB1baexHGcMzC2y1O1kpTrpaH3I80hrIZFtYoA2xKQ1j67uoC6vm1PhsJB6qhs9T7zmWZ1VtleJTYGNZ_bYY2wo65qJHFB5TXkevJUVe2G39kB_W1TKB6g_GSwb4a5e4D_Sjp7b7RZpyIKHT1_UE1H4RXgR9Qi68K4WVaJXJUS6T4PHrRc4PeGUoJLQFUGxYokWIf456G32GwGgvUSX76K77pVv4Y-kT3v5eEJdYxlS4EVT13a17KWd0DdLje0Ae69q_DQSlrHVLUrADvuZMeM8jxyPQvDb7ETKLsSUeHm73KOCGLStcGQ3pB49nt3d9XdWCcUwUrmbBF2G7HsRgTNbj16G6QUcWroQEqNrBG49aO9mMZ0NwSn5d3oNuXSXjLdGBXM1ukLZ-GNrZDYw5KXU102_5VpHpjIHrZh0dXg3Q9eucKe6EkFbH65-O5VaQWUnR5WJpt6-fl_l0iHqHnKXbgL6tjeerCqZWDvFsOak05R-hosAoQs_Ni0EsgZqHwR_VlG86fsSwCVU3_sDKTNs_Je08ewJ_bbMB5Tq6k1Sxs8Aw8R96EwjQLp3z-Zva1myU-KerYYVDl5BdvgPqbD8Xmst-z6vrP3CJbtr8jgqVS7RWy_cJOA8KCZ6IS_75QT7Gblq6UGFkG7zCCBuswggTToAMCAQICEzMAAAbTtnznKsOrB-gAAAAABtMwDQYJKoZIhvcNAQELBQAwgYwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xNjA0BgNVBAMTLU1pY3Jvc29mdCBUUE0gUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgMjAxNDAeFw0yMTA2MTAxODU0MzZaFw0yNzA2MTAxODU0MzZaMEExPzA9BgNVBAMTNkVVUy1OVEMtS0VZSUQtRTRBODY2NkY4RjRDNkQ5QzM5MzJBOTQ4ODQ3NzgwQTY4MTBDNDIxMzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAJA7GLwHWWbn2H8DRppxQfre4zll1sgE3Wxt9DTYWt5-v-xKwCQb6z_7F1py7LMe58qLqglAgVhS6nEvN2puZ1GzejdsFFxz2gyEfH1y-X3RGp0dxS6UKwEtmksaMEKIRQn2GgKdUkiuvkaxaoznuExoTPyu0aXk6yFsX5KEDu9UZCgt66bRy6m3KIRnn1VK2frZfqGYi8C8x9Q69oGG316tUwAIm3ypDtv3pREXsDLYE1U5Irdv32hzJ4CqqPyau-qJS18b8CsjvgOppwXRSwpOmU7S3xqo-F7h1eeFw2tgHc7PEPt8MSSKeba8Fz6QyiLhgFr8jFUvKRzk4B41HFUMqXYawbhAtfIBiGGsGrrdNKb7MxISnH1E6yLVCQGGhXiN9U7V0h8Gn56eKzopGlubw7yMmgu8Cu2wBX_a_jFmIBHnn8YgwcRm6NvT96KclDHnFqPVm3On12bG31F7EYkIRGLbaTT6avEu9rL6AJn7Xr245Sa6dC_OSMRKqLSufxp6O6f2TH2g4kvT0Go9SeyM2_acBjIiQ0rFeBOm49H4E4VcJepf79FkljovD68imeZ5MXjxepcCzS138374Jeh7k28JePwJnjDxS8n9Dr6xOU3_wxS1gN5cW6cXSoiPGe0JM4CEyAcUtKrvpUWoTajxxnylZuvS8ou2thfH2PQlAgMBAAGjggGOMIIBijAOBgNVHQ8BAf8EBAMCAoQwGwYDVR0lBBQwEgYJKwYBBAGCNxUkBgVngQUIAzAWBgNVHSAEDzANMAsGCSsGAQQBgjcVHzASBgNVHRMBAf8ECDAGAQH_AgEAMB0GA1UdDgQWBBQ3yjAtSXrnaSNOtzy1PEXxOO1ZUDAfBgNVHSMEGDAWgBR6jArOL0hiF-KU0a5VwVLscXSkVjBwBgNVHR8EaTBnMGWgY6Bhhl9odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NybC9NaWNyb3NvZnQlMjBUUE0lMjBSb290JTIwQ2VydGlmaWNhdGUlMjBBdXRob3JpdHklMjAyMDE0LmNybDB9BggrBgEFBQcBAQRxMG8wbQYIKwYBBQUHMAKGYWh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY2VydHMvTWljcm9zb2Z0JTIwVFBNJTIwUm9vdCUyMENlcnRpZmljYXRlJTIwQXV0aG9yaXR5JTIwMjAxNC5jcnQwDQYJKoZIhvcNAQELBQADggIBAFZTSitCISvll6i6rPUPd8Wt2mogRw6I_c-dWQzdc9-SY9iaIGXqVSPKKOlAYU2ju7nvN6AvrIba6sngHeU0AUTeg1UZ5-bDFOWdSgPaGyH_EN_l-vbV6SJPzOmZHJOHfw2WT8hjlFaTaKYRXxzFH7PUR4nxGRbWtdIGgQhUlWg5oo_FO4bvLKfssPSONn684qkAVierq-ly1WeqJzOYhd4EylgVJ9NL3YUhg8dYcHAieptDzF7OcDqffbuZLZUx6xcyibhWQcntAh7a3xPwqXxENsHhme_bqw_kqa-NVk-Wz4zdoiNNLRvUmCSL1WLc4JPsFJ08Ekn1kW7f9ZKnie5aw-29jEf6KIBt4lGDD3tXTfaOVvWcDbu92jMOO1dhEIj63AwQiDJgZhqnrpjlyWU_X0IVQlaPBg80AE0Y3sw1oMrY0XwdeQUjSpH6e5fTYKrNB6NMT1jXGjKIzVg8XbPWlnebP2wEhq8rYiDR31b9B9Sw_naK7Xb-Cqi-VQdUtknSjeljusrBpxGUx-EIJci0-dzeXRT5_376vyKSuYxA1Xd2jd4EknJLIAVLT3rb10DCuKGLDgafbsfTBxVoEa9hSjYOZUr_m3WV6t6I9WPYjVyhyi7fCEIG4JE7YbM4na4jg5q3DM8ibE8jyufAq0PfJZTJyi7c2Q2N_9NgnCNwZ3B1YkFyZWFYdgAjAAsABAByACCd_8vzbDg65pn7mGjcbcuJ1xU4hL4oA5IsEkFYv60irgAQABAAAwAQACAek7g2C8TeORRoKxuN7HrJ5OinVGuHzEgYODyUsF9D1wAggXPPXn-Pm_4IF0c4XVaJjmHO3EB2KBwdg_L60N0IL9xoY2VydEluZm9Yof9UQ0eAFwAiAAvQNGTLa2wT6u8SKDDdwkgaq5Cmh6jcD_6ULvM9ZmvdbwAUtMInD3WtGSdWHPWijMrW_TfYo-gAAAABPuBems3Sywu4aQsGAe85iOosjtXIACIAC5FPRiZSJzjYMNnAz9zFtM62o57FJwv8F5gNEcioqhHwACIACyVXxq1wZhDsqTqdYr7vQUUJ3vwWVrlN0ZQv5HFnHqWdaGF1dGhEYXRhWKR0puqSE8mcL3SyJJKzIM9AJiqUwalQoDl_KSULYIQe8EUAAAAACJhwWMrcS4G24TDeUNy-lgAghsS2ywFz_LWf9-lC35vC9uJTVD3ZCVdweZvESUbjXnSlAQIDJiABIVggHpO4NgvE3jkUaCsbjex6yeTop1Rrh8xIGDg8lLBfQ9ciWCCBc89ef4-b_ggXRzhdVomOYc7cQHYoHB2D8vrQ3Qgv3A", "clientDataJSON": "eyJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIiwiY2hhbGxlbmdlIjoidXpuOXUwVHgtTEJkdEdnRVJzYmtIUkJqaVV0NWkycnZtMkJCVFpyV3FFbyIsIm9yaWdpbiI6Imh0dHBzOi8vd2ViYXV0aG4uaW8iLCJjcm9zc09yaWdpbiI6ZmFsc2V9" } - }`, + }`, // TPM attestation with RSA SHA1 `{ "rawId": "UJDoUJoGiDQF_EEZ3G_z9Lfq16_KFaXtMTjwTUrrRlc", @@ -107,74 +119,443 @@ func TestTPMAttestationVerificationFailAttStatement(t *testing.T) { AttestationObject{AttStatement: defaultAttStatement}, "Unable to decode TPMT_PUBLIC in attestation statement", }, + { + "TPM Negative Test Unsupported Public Key Type", + AttestationObject{AttStatement: map[string]interface{}{"ver": "2.0", "alg": int64(0), "x5c": []interface{}{}, "sig": []byte{}, "certInfo": []byte{}, "pubArea": makeDefaultRSAPublicBytes()}, AuthData: AuthenticatorData{AttData: AttestedCredentialData{CredentialPublicKey: []byte{}}}}, + "Unsupported Public Key Type", + }, } for _, tt := range tests { - attestationKey, _, err := verifyTPMFormat(tt.att, nil) + attestationType, _, err := verifyTPMFormat(tt.att, nil) if tt.wantErr != "" { assert.Contains(t, err.Error(), tt.wantErr) } else { - assert.Equal(t, "tpm", attestationKey) + assert.Equal(t, "attca", attestationType) } } } -var defaultAttStatement = map[string]interface{}{"ver": "2.0", "alg": int64(0), "x5c": []interface{}{}, "sig": []byte{}, "certInfo": []byte{}, "pubArea": []byte{}} +func makeDefaultRSAPublicBytes() []byte { + r, _ := defaultRSAPublic.Encode() + return r +} + +var ( + defaultRSAPublic = tpm2.Public{ + Type: tpm2.AlgRSA, + NameAlg: tpm2.AlgSHA256, + Attributes: tpm2.FlagSignerDefault, + RSAParameters: &tpm2.RSAParams{ + Sign: &tpm2.SigScheme{ + Alg: tpm2.AlgRSASSA, + Hash: tpm2.AlgSHA256, + }, + KeyBits: 2048, + }, + } + + defaultECCPublic = tpm2.Public{ + Type: tpm2.AlgECC, + NameAlg: tpm2.AlgSHA256, + Attributes: tpm2.FlagSignerDefault, + ECCParameters: &tpm2.ECCParams{ + Sign: &tpm2.SigScheme{ + Alg: tpm2.AlgECDSA, + Hash: tpm2.AlgSHA256, + }, + CurveID: tpm2.CurveNISTP256, + }, + } +) + +var defaultAttStatement = map[string]interface{}{"ver": "2.0", "alg": int64(-257), "x5c": []interface{}{}, "sig": []byte{}, "certInfo": []byte{}, "pubArea": []byte{}} + +type CredentialPublicKey struct { + KeyType int64 `cbor:"1,keyasint" json:"kty"` + Algorithm int64 `cbor:"3,keyasint" json:"alg"` + Curve int64 `cbor:"-1,keyasint,omitempty" json:"crv"` + XCoord []byte `cbor:"-2,keyasint,omitempty" json:"x"` + YCoord []byte `cbor:"-3,keyasint,omitempty" json:"y"` + Modulus []byte `cbor:"-1,keyasint,omitempty" json:"n"` + Exponent []byte `cbor:"-2,keyasint,omitempty" json:"e"` +} + +func corruptBytes(in []byte) []byte { + out := make([]byte, len(in)) + copy(out, in) + out[len(in)-1] ^= 0xff + return out +} + +func uint32ToBytes(i uint32) []byte { + t := make([]byte, 4) + binary.LittleEndian.PutUint32(t, i) + o := make([]byte, 3) + copy(o, t) + return o +} + +func getTPMAttestionKeys() ([]byte, []byte, []byte, rsa.PrivateKey, ecdsa.PrivateKey, error) { + rsaKey, err := rsa.GenerateKey(rand.Reader, 2048) + if err != nil { + return nil, nil, nil, rsa.PrivateKey{}, ecdsa.PrivateKey{}, err + } + + r := webauthncose.RSAPublicKeyData{ + PublicKeyData: webauthncose.PublicKeyData{ + KeyType: int64(webauthncose.RSAKey), + Algorithm: int64(webauthncose.AlgRS256), + }, + Modulus: rsaKey.N.Bytes(), + Exponent: uint32ToBytes(uint32(rsaKey.E)), + } + + eccKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) + if err != nil { + return nil, nil, nil, rsa.PrivateKey{}, ecdsa.PrivateKey{}, err + } + + c := CredentialPublicKey{ + KeyType: int64(webauthncose.EllipticKey), + Algorithm: int64(webauthncose.AlgES256), + Curve: int64(webauthncose.P256), + XCoord: eccKey.X.Bytes(), + YCoord: eccKey.Y.Bytes(), + } + + e := webauthncose.EC2PublicKeyData{ + PublicKeyData: webauthncose.PublicKeyData{ + KeyType: c.KeyType, + Algorithm: c.Algorithm, + }, + Curve: c.Curve, + XCoord: c.XCoord, + YCoord: c.YCoord, + } + + okpKey, _, err := ed25519.GenerateKey(rand.Reader) + if err != nil { + return nil, nil, nil, rsa.PrivateKey{}, ecdsa.PrivateKey{}, err + } + o := webauthncose.OKPPublicKeyData{ + PublicKeyData: webauthncose.PublicKeyData{ + KeyType: int64(webauthncose.OctetKey), + Algorithm: int64(webauthncose.AlgEdDSA), + }, + Curve: int64(webauthncose.Ed25519), + XCoord: okpKey, + } + + epk, err := webauthncbor.Marshal(e) + if err != nil { + return nil, nil, nil, rsa.PrivateKey{}, ecdsa.PrivateKey{}, err + } + rpk, err := webauthncbor.Marshal(r) + if err != nil { + return nil, nil, nil, rsa.PrivateKey{}, ecdsa.PrivateKey{}, err + } + opk, err := webauthncbor.Marshal(o) + return epk, rpk, opk, *rsaKey, *eccKey, err +} func TestTPMAttestationVerificationFailPubArea(t *testing.T) { + + epk, rpk, opk, rsaKey, eccKey, err := getTPMAttestionKeys() + if err != nil { + t.Fatal(err) + } + tests := []struct { - name string - public googletpm.Public - wantErr string - }{} + name string + keyType webauthncose.COSEKeyType + rsaParams tpm2.RSAParams + eccParams tpm2.ECCParams + cpk []byte + wantErr string + }{ + { + "TPM Negative Test pubArea curve mismatch", + webauthncose.EllipticKey, + tpm2.RSAParams{}, + tpm2.ECCParams{CurveID: tpm2.CurveNISTP224, Point: tpm2.ECPoint{XRaw: eccKey.X.Bytes(), YRaw: eccKey.Y.Bytes()}}, + epk, + "Mismatch between ECCParameters in pubArea and credentialPublicKey", + }, + { + "TPM Negative Test pubArea X mismatch", + webauthncose.EllipticKey, + tpm2.RSAParams{}, + tpm2.ECCParams{CurveID: tpm2.CurveNISTP256, Point: tpm2.ECPoint{XRaw: corruptBytes(eccKey.X.Bytes()), YRaw: eccKey.Y.Bytes()}}, + epk, + "Mismatch between ECCParameters in pubArea and credentialPublicKey", + }, + { + "TPM Negative Test pubArea Y mismatch", + webauthncose.EllipticKey, + tpm2.RSAParams{}, + tpm2.ECCParams{CurveID: tpm2.CurveNISTP256, Point: tpm2.ECPoint{XRaw: eccKey.X.Bytes(), YRaw: corruptBytes(eccKey.Y.Bytes())}}, + epk, + "Mismatch between ECCParameters in pubArea and credentialPublicKey", + }, + { + "TPM Negative Test pubArea N mismatch", + webauthncose.RSAKey, + tpm2.RSAParams{ModulusRaw: corruptBytes(rsaKey.N.Bytes()), ExponentRaw: uint32(rsaKey.E)}, + tpm2.ECCParams{}, + rpk, + "Mismatch between RSAParameters in pubArea and credentialPublicKey", + }, + { + "TPM Negative Test pubArea E mismatch", + webauthncose.RSAKey, + tpm2.RSAParams{ModulusRaw: rsaKey.N.Bytes(), ExponentRaw: uint32(rsaKey.E + 1)}, + tpm2.ECCParams{}, + rpk, + "Mismatch between RSAParameters in pubArea and credentialPublicKey", + }, + { + "TPM Negative Test pubArea unsupported key type", + webauthncose.OctetKey, + tpm2.RSAParams{}, + tpm2.ECCParams{}, + opk, + "Unsupported Public Key Type", + }, + } for _, tt := range tests { attStmt := make(map[string]interface{}, len(defaultAttStatement)) for id, v := range defaultAttStatement { attStmt[id] = v } - //attStmt["pubArea"], _ = tt.public.Encode() + public := tpm2.Public{} + switch tt.keyType { + case webauthncose.EllipticKey: + public = defaultECCPublic + public.ECCParameters.CurveID = tt.eccParams.CurveID + public.ECCParameters.Point.XRaw = tt.eccParams.Point.XRaw + public.ECCParameters.Point.YRaw = tt.eccParams.Point.YRaw + case webauthncose.RSAKey: + public = defaultRSAPublic + public.RSAParameters.ExponentRaw = tt.rsaParams.ExponentRaw + public.RSAParameters.ModulusRaw = tt.rsaParams.ModulusRaw + case webauthncose.OctetKey: + public = defaultECCPublic + } + + attStmt["pubArea"], _ = public.Encode() att := AttestationObject{ AttStatement: attStmt, + AuthData: AuthenticatorData{ + AttData: AttestedCredentialData{ + CredentialPublicKey: tt.cpk, + }, + }, } - attestationKey, _, err := verifyTPMFormat(att, nil) + + attestationType, _, err := verifyTPMFormat(att, nil) if tt.wantErr != "" { assert.Contains(t, err.Error(), tt.wantErr) } else { - assert.Equal(t, "tpm", attestationKey) + assert.Equal(t, "attca", attestationType) } } } func TestTPMAttestationVerificationFailCertInfo(t *testing.T) { + attStmt := make(map[string]interface{}, len(defaultAttStatement)) + for id, v := range defaultAttStatement { + attStmt[id] = v + } + rsaKey, _ := rsa.GenerateKey(rand.Reader, 2048) + + r := webauthncose.RSAPublicKeyData{ + PublicKeyData: webauthncose.PublicKeyData{ + KeyType: int64(webauthncose.RSAKey), + Algorithm: int64(webauthncose.AlgRS256), + }, + Modulus: rsaKey.N.Bytes(), + Exponent: uint32ToBytes(uint32(rsaKey.E)), + } + + public := defaultRSAPublic + public.RSAParameters.ExponentRaw = uint32(rsaKey.E) + public.RSAParameters.ModulusRaw = rsaKey.N.Bytes() + attStmt["pubArea"], _ = public.Encode() + rpk, _ := webauthncbor.Marshal(r) + att := AttestationObject{ + AttStatement: attStmt, + AuthData: AuthenticatorData{ + AttData: AttestedCredentialData{ + CredentialPublicKey: rpk, + }, + }, + } + + f := webauthncose.HasherFromCOSEAlg(webauthncose.AlgRS256) + h := f() + h.Write(att.RawAuthData) + extraData := h.Sum(nil) + tests := []struct { - name string - att AttestationObject - clientDataHash [32]byte - wantErr string - }{} + name string + certInfo tpm2.AttestationData + wantErr string + }{ + { + "TPM Negative Test CertInfo invalid certInfo", + tpm2.AttestationData{}, + "decoding Magic/Type: EOF", + }, + { + "TPM Negative Test CertInfo magic value not 0xff544347", + tpm2.AttestationData{Magic: 42, Type: tpm2.TagAttestCreation, AttestedCreationInfo: &tpm2.CreationInfo{}}, + "incorrect magic value: 2a", + }, + { + "TPM Negative Test CertInfo type not TagAttestCertify", + tpm2.AttestationData{Magic: 0xff544347, Type: tpm2.TagAttestCreation, AttestedCreationInfo: &tpm2.CreationInfo{}}, + "Type is not set to TPM_ST_ATTEST_CERTIFY", + }, + { + "TPM Negative Test CertInfo type not TagAttestCertify", + tpm2.AttestationData{Magic: 0xff544347, Type: tpm2.TagAttestCertify, AttestedCertifyInfo: &tpm2.CertifyInfo{}}, + "ExtraData is not set to hash of attToBeSigned", + }, + { + "TPM Negative Test CertInfo Name/pubArea mismatch", + tpm2.AttestationData{Magic: 0xff544347, Type: tpm2.TagAttestCertify, AttestedCertifyInfo: &tpm2.CertifyInfo{Name: tpm2.Name{Digest: nil}}, ExtraData: extraData}, + "Name doesn't have a Digest, can't compare to Public", + }, + { + "TPM Negative Test CertInfo Name/pubArea mismatch", + tpm2.AttestationData{Magic: 0xff544347, Type: tpm2.TagAttestCertify, AttestedCertifyInfo: &tpm2.CertifyInfo{Name: tpm2.Name{Digest: &tpm2.HashValue{Alg: tpm2.AlgSHA256, Value: extraData}}}, ExtraData: h.Sum(nil)}, + "Hash value mismatch attested and pubArea", + }, + } for _, tt := range tests { - attestationKey, _, err := verifyTPMFormat(tt.att, tt.clientDataHash[:]) + certInfo, err := tt.certInfo.Encode() + if tt.certInfo.Magic != 0 && err != nil { + t.Fatal(err) + } + att.AttStatement["certInfo"] = certInfo + attestationType, _, err := verifyTPMFormat(att, nil) if tt.wantErr != "" { assert.Contains(t, err.Error(), tt.wantErr) } else { - assert.Equal(t, "tpm", attestationKey) + assert.Equal(t, "attca", attestationType) } } } +var ( + x5cTemplate = x509.Certificate{ + SerialNumber: big.NewInt(0), + Version: 3, + Subject: pkix.Name{ + Country: []string{"US"}, + Organization: []string{"Duo Labs"}, + OrganizationalUnit: []string{"Authenticator Attestation"}, + CommonName: "WebAuthn.io", + }, + Extensions: []pkix.Extension{ + { + Id: asn1.ObjectIdentifier([]int{1, 3, 6, 1, 4, 1, 45724, 1, 1, 4}), + Critical: false, + Value: []byte{ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + }, + }, + IsCA: false, + } +) + func TestTPMAttestationVerificationFailX5c(t *testing.T) { + attStmt := make(map[string]interface{}, len(defaultAttStatement)) + for id, v := range defaultAttStatement { + attStmt[id] = v + } + rsaKey, _ := rsa.GenerateKey(rand.Reader, 2048) + + r := webauthncose.RSAPublicKeyData{ + PublicKeyData: webauthncose.PublicKeyData{ + KeyType: int64(webauthncose.RSAKey), + Algorithm: int64(webauthncose.AlgRS256), + }, + Modulus: rsaKey.N.Bytes(), + Exponent: uint32ToBytes(uint32(rsaKey.E)), + } + + public := defaultRSAPublic + public.RSAParameters.ExponentRaw = uint32(rsaKey.E) + public.RSAParameters.ModulusRaw = rsaKey.N.Bytes() + pubBytes, _ := public.Encode() + attStmt["pubArea"] = pubBytes + rpk, _ := webauthncbor.Marshal(r) + att := AttestationObject{ + AttStatement: attStmt, + AuthData: AuthenticatorData{ + AttData: AttestedCredentialData{ + CredentialPublicKey: rpk, + }, + }, + } + + f := webauthncose.HasherFromCOSEAlg(webauthncose.AlgRS256) + h := f() + h.Write(att.RawAuthData) + extraData := h.Sum(nil) + + h.Reset() + h.Write(pubBytes) + pubName := h.Sum(nil) + + certInfo := tpm2.AttestationData{ + Magic: 0xff544347, + Type: tpm2.TagAttestCertify, + AttestedCertifyInfo: &tpm2.CertifyInfo{ + Name: tpm2.Name{ + Digest: &tpm2.HashValue{ + Alg: tpm2.AlgSHA256, + Value: pubName, + }, + }, + }, + ExtraData: extraData, + } + attStmt["certInfo"], _ = certInfo.Encode() + + makeX5c := func(b []byte) []interface{} { + q := make([]interface{}, 1) + q[0] = b + return q + } + tests := []struct { - name string - att AttestationObject - clientDataHash [32]byte - wantErr string - }{} + name string + x5c []interface{} + wantErr string + }{ + { + "TPM Negative Test x5c empty", + make([]interface{}, 1), + "Error getting certificate from x5c cert chain", + }, + { + "TPM Negative Test x5c can't parse", + makeX5c(make([]byte, 1)), + "Error parsing certificate from ASN.1", + }, + } for _, tt := range tests { - attestationKey, _, err := verifyTPMFormat(tt.att, tt.clientDataHash[:]) + att.AttStatement["x5c"] = tt.x5c + attestationType, _, err := verifyTPMFormat(att, nil) if tt.wantErr != "" { assert.Contains(t, err.Error(), tt.wantErr) } else { - assert.Equal(t, "tpm", attestationKey) + assert.Equal(t, "attca", attestationType) } } } diff --git a/protocol/googletpm/certinfo.go b/protocol/googletpm/certinfo.go deleted file mode 100644 index 08ae3a99..00000000 --- a/protocol/googletpm/certinfo.go +++ /dev/null @@ -1,282 +0,0 @@ -package googletpm - -import ( - "bytes" - "crypto/sha1" - "crypto/sha256" - "crypto/sha512" - "fmt" - "hash" -) - -// DecodeAttestationData decode a TPMS_ATTEST message. No error is returned if -// the input has extra trailing data. -func DecodeAttestationData(in []byte) (*AttestationData, error) { - buf := bytes.NewBuffer(in) - - var ad AttestationData - if err := UnpackBuf(buf, &ad.Magic, &ad.Type); err != nil { - return nil, fmt.Errorf("decoding Magic/Type: %v", err) - } - n, err := decodeName(buf) - if err != nil { - return nil, fmt.Errorf("decoding QualifiedSigner: %v", err) - } - ad.QualifiedSigner = *n - if err := UnpackBuf(buf, &ad.ExtraData, &ad.ClockInfo, &ad.FirmwareVersion); err != nil { - return nil, fmt.Errorf("decoding ExtraData/ClockInfo/FirmwareVersion: %v", err) - } - - // The spec specifies several other types of attestation data. We only need - // parsing of Certify & Creation attestation data for now. If you need - // support for other attestation types, add them here. - switch ad.Type { - case TagAttestCertify: - if ad.AttestedCertifyInfo, err = decodeCertifyInfo(buf); err != nil { - return nil, fmt.Errorf("decoding AttestedCertifyInfo: %v", err) - } - case TagAttestCreation: - if ad.AttestedCreationInfo, err = decodeCreationInfo(buf); err != nil { - return nil, fmt.Errorf("decoding AttestedCreationInfo: %v", err) - } - case TagAttestQuote: - if ad.AttestedQuoteInfo, err = decodeQuoteInfo(buf); err != nil { - return nil, fmt.Errorf("decoding AttestedQuoteInfo: %v", err) - } - default: - return nil, fmt.Errorf("only Certify & Creation attestation structures are supported, got type 0x%x", ad.Type) - } - - return &ad, nil -} - -// AttestationData contains data attested by TPM commands (like Certify). -type AttestationData struct { - Magic uint32 - Type Tag - QualifiedSigner Name - ExtraData []byte - ClockInfo ClockInfo - FirmwareVersion uint64 - AttestedCertifyInfo *CertifyInfo - AttestedQuoteInfo *QuoteInfo - AttestedCreationInfo *CreationInfo -} - -// Tag is a command tag. -type Tag uint16 - -type Name struct { - Handle *Handle - Digest *HashValue -} - -// A Handle is a reference to a TPM object. -type Handle uint32 -type HashValue struct { - Alg Algorithm - Value []byte -} - -// ClockInfo contains TPM state info included in AttestationData. -type ClockInfo struct { - Clock uint64 - ResetCount uint32 - RestartCount uint32 - Safe byte -} - -// CertifyInfo contains Certify-specific data for TPMS_ATTEST. -type CertifyInfo struct { - Name Name - QualifiedName Name -} - -// QuoteInfo represents a TPMS_QUOTE_INFO structure. -type QuoteInfo struct { - PCRSelection PCRSelection - PCRDigest []byte -} - -// PCRSelection contains a slice of PCR indexes and a hash algorithm used in -// them. -type PCRSelection struct { - Hash Algorithm - PCRs []int -} - -// CreationInfo contains Creation-specific data for TPMS_ATTEST. -type CreationInfo struct { - Name Name - // Most TPM2B_Digest structures contain a TPMU_HA structure - // and get parsed to HashValue. This is never the case for the - // digest in TPMS_CREATION_INFO. - OpaqueDigest []byte -} - -func decodeName(in *bytes.Buffer) (*Name, error) { - var nameBuf []byte - if err := UnpackBuf(in, &nameBuf); err != nil { - return nil, err - } - - name := new(Name) - switch len(nameBuf) { - case 0: - // No name is present. - case 4: - name.Handle = new(Handle) - if err := UnpackBuf(bytes.NewBuffer(nameBuf), name.Handle); err != nil { - return nil, fmt.Errorf("decoding Handle: %v", err) - } - default: - var err error - name.Digest, err = decodeHashValue(bytes.NewBuffer(nameBuf)) - if err != nil { - return nil, fmt.Errorf("decoding Digest: %v", err) - } - } - return name, nil -} - -func decodeHashValue(in *bytes.Buffer) (*HashValue, error) { - var hv HashValue - if err := UnpackBuf(in, &hv.Alg); err != nil { - return nil, fmt.Errorf("decoding Alg: %v", err) - } - hfn, ok := hashConstructors[hv.Alg] - if !ok { - return nil, fmt.Errorf("unsupported hash algorithm type 0x%x", hv.Alg) - } - hv.Value = make([]byte, hfn().Size()) - if _, err := in.Read(hv.Value); err != nil { - return nil, fmt.Errorf("decoding Value: %v", err) - } - return &hv, nil -} - -// HashConstructor returns a function that can be used to make a -// hash.Hash using the specified algorithm. An error is returned -// if the algorithm is not a hash algorithm. -func (a Algorithm) HashConstructor() (func() hash.Hash, error) { - c, ok := hashConstructors[a] - if !ok { - return nil, fmt.Errorf("algorithm not supported: 0x%x", a) - } - return c, nil -} - -var hashConstructors = map[Algorithm]func() hash.Hash{ - AlgSHA1: sha1.New, - AlgSHA256: sha256.New, - AlgSHA384: sha512.New384, - AlgSHA512: sha512.New, -} - -// TPM Structure Tags. Tags are used to disambiguate structures, similar to Alg -// values: tag value defines what kind of data lives in a nested field. -const ( - TagNull Tag = 0x8000 - TagNoSessions Tag = 0x8001 - TagSessions Tag = 0x8002 - TagAttestCertify Tag = 0x8017 - TagAttestQuote Tag = 0x8018 - TagAttestCreation Tag = 0x801a - TagHashCheck Tag = 0x8024 -) - -func decodeCertifyInfo(in *bytes.Buffer) (*CertifyInfo, error) { - var ci CertifyInfo - - n, err := decodeName(in) - if err != nil { - return nil, fmt.Errorf("decoding Name: %v", err) - } - ci.Name = *n - - n, err = decodeName(in) - if err != nil { - return nil, fmt.Errorf("decoding QualifiedName: %v", err) - } - ci.QualifiedName = *n - - return &ci, nil -} - -func decodeCreationInfo(in *bytes.Buffer) (*CreationInfo, error) { - var ci CreationInfo - - n, err := decodeName(in) - if err != nil { - return nil, fmt.Errorf("decoding Name: %v", err) - } - ci.Name = *n - - if err := UnpackBuf(in, &ci.OpaqueDigest); err != nil { - return nil, fmt.Errorf("decoding Digest: %v", err) - } - - return &ci, nil -} - -func decodeQuoteInfo(in *bytes.Buffer) (*QuoteInfo, error) { - var out QuoteInfo - sel, err := decodeTPMLPCRSelection(in) - if err != nil { - return nil, fmt.Errorf("decoding PCRSelection: %v", err) - } - out.PCRSelection = sel - if err := UnpackBuf(in, &out.PCRDigest); err != nil { - return nil, fmt.Errorf("decoding PCRDigest: %v", err) - } - return &out, nil -} - -func decodeTPMLPCRSelection(buf *bytes.Buffer) (PCRSelection, error) { - var count uint32 - var sel PCRSelection - if err := UnpackBuf(buf, &count); err != nil { - return sel, err - } - switch count { - case 0: - sel.Hash = AlgUnknown - return sel, nil - case 1: // We only support decoding of a single PCRSelection. - default: - return sel, fmt.Errorf("decoding TPML_PCR_SELECTION list longer than 1 is not supported (got length %d)", count) - } - - // See comment in encodeTPMLPCRSelection for details on this format. - var ts tpmsPCRSelection - if err := UnpackBuf(buf, &ts.Hash, &ts.Size); err != nil { - return sel, err - } - ts.PCRs = make([]byte, ts.Size) - if _, err := buf.Read(ts.PCRs); err != nil { - return sel, err - } - - sel.Hash = ts.Hash - for i := 0; i < int(ts.Size); i++ { - for j := 0; j < 8; j++ { - set := ts.PCRs[i] & byte(1<= size { - *b = (*b)[:size] - } else { - *b = append(*b, make([]byte, size-len(*b))...) - } - case *[]Handle: - if len(*b) >= size { - *b = (*b)[:size] - } else { - *b = append(*b, make([]Handle, size-len(*b))...) - } - default: - return fmt.Errorf("can't fill pointer to %T, only []byte or []Handle slices", e) - } - - if err := binary.Read(buf, binary.BigEndian, e); err != nil { - return err - } - default: - if err := binary.Read(buf, binary.BigEndian, e); err != nil { - return err - } - } - - } - - return nil -} - -// lengthPrefixSize is the size in bytes of length prefix for byte slices. -// -// In TPM 1.2 this is 4 bytes. -// In TPM 2.0 this is 2 bytes. -var lengthPrefixSize int - -const ( - tpm12PrefixSize = 4 - tpm20PrefixSize = 2 -) - -// UseTPM20LengthPrefixSize makes Pack/Unpack use TPM 2.0 encoding for byte -// arrays. -func UseTPM20LengthPrefixSize() { - lengthPrefixSize = tpm20PrefixSize -} diff --git a/protocol/googletpm/pubarea.go b/protocol/googletpm/pubarea.go deleted file mode 100644 index dd3288ff..00000000 --- a/protocol/googletpm/pubarea.go +++ /dev/null @@ -1,240 +0,0 @@ -package googletpm - -import ( - "bytes" - "fmt" - "math/big" -) - -// DecodePublic decodes a TPMT_PUBLIC message. No error is returned if -// the input has extra trailing data. -func DecodePublic(buf []byte) (Public, error) { - in := bytes.NewBuffer(buf) - var pub Public - var err error - if err = UnpackBuf(in, &pub.Type, &pub.NameAlg, &pub.Attributes, &pub.AuthPolicy); err != nil { - return pub, fmt.Errorf("decoding TPMT_PUBLIC: %v", err) - } - - switch pub.Type { - case AlgRSA: - pub.RSAParameters, err = decodeRSAParams(in) - case AlgECC: - pub.ECCParameters, err = decodeECCParams(in) - default: - err = fmt.Errorf("unsupported type in TPMT_PUBLIC: %v", pub.Type) - } - return pub, err -} - -// Public contains the public area of an object. -type Public struct { - Type Algorithm - NameAlg Algorithm - Attributes KeyProp - AuthPolicy []byte - - // If Type is AlgKeyedHash, then do not set these. - // Otherwise, only one of the Parameters fields should be set. When encoding/decoding, - // one will be picked based on Type. - RSAParameters *RSAParams - ECCParameters *ECCParams -} - -// Algorithm represents a TPM_ALG_ID value. -type Algorithm uint16 - -// KeyProp is a bitmask used in Attributes field of key templates. Individual -// flags should be OR-ed to form a full mask. -type KeyProp uint32 - -// Key properties. -const ( - FlagFixedTPM KeyProp = 0x00000002 - FlagFixedParent KeyProp = 0x00000010 - FlagSensitiveDataOrigin KeyProp = 0x00000020 - FlagUserWithAuth KeyProp = 0x00000040 - FlagAdminWithPolicy KeyProp = 0x00000080 - FlagNoDA KeyProp = 0x00000400 - FlagRestricted KeyProp = 0x00010000 - FlagDecrypt KeyProp = 0x00020000 - FlagSign KeyProp = 0x00040000 - - FlagSealDefault = FlagFixedTPM | FlagFixedParent - FlagSignerDefault = FlagSign | FlagRestricted | FlagFixedTPM | - FlagFixedParent | FlagSensitiveDataOrigin | FlagUserWithAuth - FlagStorageDefault = FlagDecrypt | FlagRestricted | FlagFixedTPM | - FlagFixedParent | FlagSensitiveDataOrigin | FlagUserWithAuth -) - -func decodeRSAParams(in *bytes.Buffer) (*RSAParams, error) { - var params RSAParams - var err error - - if params.Symmetric, err = decodeSymScheme(in); err != nil { - return nil, fmt.Errorf("decoding Symmetric: %v", err) - } - if params.Sign, err = decodeSigScheme(in); err != nil { - return nil, fmt.Errorf("decoding Sign: %v", err) - } - var modBytes []byte - if err := UnpackBuf(in, ¶ms.KeyBits, ¶ms.Exponent, &modBytes); err != nil { - return nil, fmt.Errorf("decoding KeyBits, Exponent, Modulus: %v", err) - } - if params.Exponent == 0 { - params.encodeDefaultExponentAsZero = true - params.Exponent = defaultRSAExponent - } - params.Modulus = new(big.Int).SetBytes(modBytes) - return ¶ms, nil -} - -const defaultRSAExponent = 1<<16 + 1 - -// RSAParams represents parameters of an RSA key pair. -// -// Symmetric and Sign may be nil, depending on key Attributes in Public. -// -// One of Modulus and ModulusRaw must always be non-nil. Modulus takes -// precedence. ModulusRaw is used for key templates where the field named -// "unique" must be a byte array of all zeroes. -type RSAParams struct { - Symmetric *SymScheme - Sign *SigScheme - KeyBits uint16 - // The default Exponent (65537) has two representations; the - // 0 value, and the value 65537. - // If encodeDefaultExponentAsZero is set, an exponent of 65537 - // will be encoded as zero. This is necessary to produce an identical - // encoded bitstream, so Name digest calculations will be correct. - encodeDefaultExponentAsZero bool - Exponent uint32 - ModulusRaw []byte - Modulus *big.Int -} - -// SymScheme represents a symmetric encryption scheme. -type SymScheme struct { - Alg Algorithm - KeyBits uint16 - Mode Algorithm -} // SigScheme represents a signing scheme. -type SigScheme struct { - Alg Algorithm - Hash Algorithm - Count uint32 -} - -func decodeSigScheme(in *bytes.Buffer) (*SigScheme, error) { - var scheme SigScheme - if err := UnpackBuf(in, &scheme.Alg); err != nil { - return nil, fmt.Errorf("decoding Alg: %v", err) - } - if scheme.Alg == AlgNull { - return nil, nil - } - if err := UnpackBuf(in, &scheme.Hash); err != nil { - return nil, fmt.Errorf("decoding Hash: %v", err) - } - if scheme.Alg.UsesCount() { - if err := UnpackBuf(in, &scheme.Count); err != nil { - return nil, fmt.Errorf("decoding Count: %v", err) - } - } - return &scheme, nil -} - -// UsesCount returns true if a signature algorithm uses count value. -func (a Algorithm) UsesCount() bool { - return a == AlgECDAA -} - -func decodeKDFScheme(in *bytes.Buffer) (*KDFScheme, error) { - var scheme KDFScheme - if err := UnpackBuf(in, &scheme.Alg); err != nil { - return nil, fmt.Errorf("decoding Alg: %v", err) - } - if scheme.Alg == AlgNull { - return nil, nil - } - if err := UnpackBuf(in, &scheme.Hash); err != nil { - return nil, fmt.Errorf("decoding Hash: %v", err) - } - return &scheme, nil -} -func decodeSymScheme(in *bytes.Buffer) (*SymScheme, error) { - var scheme SymScheme - if err := UnpackBuf(in, &scheme.Alg); err != nil { - return nil, fmt.Errorf("decoding Alg: %v", err) - } - if scheme.Alg == AlgNull { - return nil, nil - } - if err := UnpackBuf(in, &scheme.KeyBits, &scheme.Mode); err != nil { - return nil, fmt.Errorf("decoding KeyBits, Mode: %v", err) - } - return &scheme, nil -} -func decodeECCParams(in *bytes.Buffer) (*ECCParams, error) { - var params ECCParams - var err error - - if params.Symmetric, err = decodeSymScheme(in); err != nil { - return nil, fmt.Errorf("decoding Symmetric: %v", err) - } - if params.Sign, err = decodeSigScheme(in); err != nil { - return nil, fmt.Errorf("decoding Sign: %v", err) - } - if err := UnpackBuf(in, ¶ms.CurveID); err != nil { - return nil, fmt.Errorf("decoding CurveID: %v", err) - } - if params.KDF, err = decodeKDFScheme(in); err != nil { - return nil, fmt.Errorf("decoding KDF: %v", err) - } - var x, y []byte - if err := UnpackBuf(in, &x, &y); err != nil { - return nil, fmt.Errorf("decoding Point: %v", err) - } - params.Point.X = new(big.Int).SetBytes(x) - params.Point.Y = new(big.Int).SetBytes(y) - return ¶ms, nil -} - -// ECCParams represents parameters of an ECC key pair. -// -// Symmetric, Sign and KDF may be nil, depending on key Attributes in Public. -type ECCParams struct { - Symmetric *SymScheme - Sign *SigScheme - CurveID EllipticCurve - KDF *KDFScheme - Point ECPoint -} - -// EllipticCurve identifies specific EC curves. -type EllipticCurve uint16 - -// ECC curves supported by TPM 2.0 spec. -const ( - CurveNISTP192 = EllipticCurve(iota + 1) - CurveNISTP224 - CurveNISTP256 - CurveNISTP384 - CurveNISTP521 - - CurveBNP256 = EllipticCurve(iota + 10) - CurveBNP638 - - CurveSM2P256 = EllipticCurve(0x0020) -) - -// ECPoint represents a ECC coordinates for a point. -type ECPoint struct { - X, Y *big.Int -} - -// KDFScheme represents a KDF (Key Derivation Function) scheme. -type KDFScheme struct { - Alg Algorithm - Hash Algorithm -} diff --git a/protocol/webauthncose/webauthncose.go b/protocol/webauthncose/webauthncose.go index 3e066205..07fce18b 100644 --- a/protocol/webauthncose/webauthncose.go +++ b/protocol/webauthncose/webauthncose.go @@ -13,8 +13,8 @@ import ( "golang.org/x/crypto/ed25519" - "github.com/go-webauthn/webauthn/protocol/googletpm" "github.com/go-webauthn/webauthn/protocol/webauthncbor" + "github.com/google/go-tpm/tpm2" ) // PublicKeyData The public key portion of a Relying Party-specific credential key pair, generated @@ -273,31 +273,28 @@ const ( Secp256k1 ) -func (k *EC2PublicKeyData) TPMCurveID() googletpm.EllipticCurve { +func (k *EC2PublicKeyData) TPMCurveID() tpm2.EllipticCurve { switch COSEEllipticCurve(k.Curve) { case P256: - return googletpm.CurveNISTP256 // TPM_ECC_NIST_P256 + return tpm2.CurveNISTP256 // TPM_ECC_NIST_P256 case P384: - return googletpm.CurveNISTP384 // TPM_ECC_NIST_P384 + return tpm2.CurveNISTP384 // TPM_ECC_NIST_P384 case P521: - return googletpm.CurveNISTP521 // TPM_ECC_NIST_P521 + return tpm2.CurveNISTP521 // TPM_ECC_NIST_P521 default: - return googletpm.EllipticCurve(0) // TPM_ECC_NONE + return tpm2.EllipticCurve(0) // TPM_ECC_NONE } } func VerifySignature(key interface{}, data []byte, sig []byte) (bool, error) { - switch key.(type) { + switch key := key.(type) { case OKPPublicKeyData: - o := key.(OKPPublicKeyData) - return o.Verify(data, sig) + return key.Verify(data, sig) case EC2PublicKeyData: - e := key.(EC2PublicKeyData) - return e.Verify(data, sig) + return key.Verify(data, sig) case RSAPublicKeyData: - r := key.(RSAPublicKeyData) - return r.Verify(data, sig) + return key.Verify(data, sig) default: return false, ErrUnsupportedKey } @@ -308,12 +305,11 @@ func DisplayPublicKey(cpk []byte) string { if err != nil { return "Cannot display key" } - switch parsedKey.(type) { + switch parsedKey := parsedKey.(type) { case RSAPublicKeyData: - pKey := parsedKey.(RSAPublicKeyData) rKey := &rsa.PublicKey{ - N: big.NewInt(0).SetBytes(pKey.Modulus), - E: int(uint(pKey.Exponent[2]) | uint(pKey.Exponent[1])<<8 | uint(pKey.Exponent[0])<<16), + N: big.NewInt(0).SetBytes(parsedKey.Modulus), + E: int(uint(parsedKey.Exponent[2]) | uint(parsedKey.Exponent[1])<<8 | uint(parsedKey.Exponent[0])<<16), } data, err := x509.MarshalPKIXPublicKey(rKey) if err != nil { @@ -325,9 +321,8 @@ func DisplayPublicKey(cpk []byte) string { }) return string(pemBytes) case EC2PublicKeyData: - pKey := parsedKey.(EC2PublicKeyData) var curve elliptic.Curve - switch COSEAlgorithmIdentifier(pKey.Algorithm) { + switch COSEAlgorithmIdentifier(parsedKey.Algorithm) { case AlgES256: curve = elliptic.P256() case AlgES384: @@ -339,8 +334,8 @@ func DisplayPublicKey(cpk []byte) string { } eKey := &ecdsa.PublicKey{ Curve: curve, - X: big.NewInt(0).SetBytes(pKey.XCoord), - Y: big.NewInt(0).SetBytes(pKey.YCoord), + X: big.NewInt(0).SetBytes(parsedKey.XCoord), + Y: big.NewInt(0).SetBytes(parsedKey.YCoord), } data, err := x509.MarshalPKIXPublicKey(eKey) if err != nil { @@ -352,12 +347,11 @@ func DisplayPublicKey(cpk []byte) string { }) return string(pemBytes) case OKPPublicKeyData: - pKey := parsedKey.(OKPPublicKeyData) - if len(pKey.XCoord) != ed25519.PublicKeySize { + if len(parsedKey.XCoord) != ed25519.PublicKeySize { return "Cannot display key" } var oKey ed25519.PublicKey = make([]byte, ed25519.PublicKeySize) - copy(oKey, pKey.XCoord) + copy(oKey, parsedKey.XCoord) data, err := marshalEd25519PublicKey(oKey) if err != nil { return "Cannot display key"