diff --git a/api/proto/teleport/legacy/types/webauthn/webauthn.proto b/api/proto/teleport/legacy/types/webauthn/webauthn.proto
index b14ae49764993..8b3f0c4a8dfe0 100644
--- a/api/proto/teleport/legacy/types/webauthn/webauthn.proto
+++ b/api/proto/teleport/legacy/types/webauthn/webauthn.proto
@@ -33,7 +33,7 @@ package webauthn;
import "gogoproto/gogo.proto";
-option go_package = "github.com/gravitational/teleport/api/types/webauthn";
+option go_package = "github.com/gravitational/teleport/api/types/webauthn;webauthnpb";
option (gogoproto.marshaler_all) = true;
option (gogoproto.unmarshaler_all) = true;
@@ -256,8 +256,9 @@ message CredentialParameter {
message RelyingPartyEntity {
string id = 1;
string name = 2;
- // URL to the icon of the Relying Party.
- string icon = 3;
+
+ reserved 3; // string icon
+ reserved "icon";
}
// User information.
@@ -273,6 +274,7 @@ message UserEntity {
// Human-palatable name for the user account, intended only for display.
// The Relying Party _should_ let the user choose this value.
string display_name = 3;
- // URL to a resource which can be the avatar image for the user.
- string icon = 4;
+
+ reserved 4; // string icon
+ reserved "icon";
}
diff --git a/api/types/webauthn/webauthn.pb.go b/api/types/webauthn/webauthn.pb.go
index a976ad09805b5..35fdb48a7605a 100644
--- a/api/types/webauthn/webauthn.pb.go
+++ b/api/types/webauthn/webauthn.pb.go
@@ -17,7 +17,7 @@
// case for _any_ of the fields mapped here, all bytes fields are transmitted
// raw/unencoded.
-package webauthn
+package webauthnpb
import (
fmt "fmt"
@@ -1093,10 +1093,8 @@ func (m *CredentialParameter) GetAlg() int32 {
// See https://www.w3.org/TR/webauthn-2/#dictdef-publickeycredentialrpentity and
// https://developer.mozilla.org/en-US/docs/Web/API/PublicKeyCredentialCreationOptions/rp.
type RelyingPartyEntity struct {
- Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
- Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
- // URL to the icon of the Relying Party.
- Icon string `protobuf:"bytes,3,opt,name=icon,proto3" json:"icon,omitempty"`
+ Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
+ Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@@ -1149,13 +1147,6 @@ func (m *RelyingPartyEntity) GetName() string {
return ""
}
-func (m *RelyingPartyEntity) GetIcon() string {
- if m != nil {
- return m.Icon
- }
- return ""
-}
-
// User information.
// See https://www.w3.org/TR/webauthn-2/#dictdef-publickeycredentialuserentity
// and
@@ -1168,9 +1159,7 @@ type UserEntity struct {
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
// Human-palatable name for the user account, intended only for display.
// The Relying Party _should_ let the user choose this value.
- DisplayName string `protobuf:"bytes,3,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty"`
- // URL to a resource which can be the avatar image for the user.
- Icon string `protobuf:"bytes,4,opt,name=icon,proto3" json:"icon,omitempty"`
+ DisplayName string `protobuf:"bytes,3,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@@ -1230,13 +1219,6 @@ func (m *UserEntity) GetDisplayName() string {
return ""
}
-func (m *UserEntity) GetIcon() string {
- if m != nil {
- return m.Icon
- }
- return ""
-}
-
func init() {
proto.RegisterType((*SessionData)(nil), "webauthn.SessionData")
proto.RegisterType((*User)(nil), "webauthn.User")
@@ -1262,74 +1244,75 @@ func init() {
}
var fileDescriptor_0d490a6db28e8798 = []byte{
- // 1062 bytes of a gzipped FileDescriptorProto
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x56, 0x4b, 0x6f, 0x1c, 0x45,
- 0x10, 0xd6, 0xec, 0xc3, 0xf1, 0xd6, 0x2e, 0x91, 0xd3, 0x5e, 0x27, 0x8b, 0x71, 0xd6, 0x9b, 0x01,
- 0xa4, 0x15, 0x7e, 0x2c, 0x32, 0x70, 0xe0, 0x29, 0xf9, 0x11, 0x84, 0x63, 0x88, 0xad, 0x89, 0x40,
- 0x82, 0xcb, 0xa8, 0x3d, 0x53, 0xec, 0x76, 0x98, 0x9d, 0x99, 0x74, 0xf7, 0xc4, 0x59, 0xf1, 0x93,
- 0xb8, 0x71, 0xe2, 0xc6, 0x15, 0x89, 0x0b, 0xbf, 0xc0, 0x44, 0x3e, 0xfa, 0x57, 0xa0, 0xee, 0x79,
- 0xee, 0xee, 0x38, 0x36, 0x20, 0xe5, 0xd6, 0x53, 0x55, 0x5f, 0x75, 0x77, 0x7d, 0xf5, 0xd5, 0x34,
- 0x6c, 0x49, 0xf4, 0x30, 0x0c, 0xb8, 0x1c, 0x78, 0x38, 0xa4, 0xce, 0x64, 0x20, 0x27, 0x21, 0x8a,
- 0xc1, 0x19, 0x9e, 0xd2, 0x48, 0x8e, 0xfc, 0x6c, 0xb1, 0x1d, 0xf2, 0x40, 0x06, 0x64, 0x31, 0xfd,
- 0x5e, 0x6d, 0x0f, 0x83, 0x61, 0xa0, 0x8d, 0x03, 0xb5, 0x8a, 0xfd, 0xe6, 0x9f, 0x15, 0x68, 0x3e,
- 0x41, 0x21, 0x58, 0xe0, 0x1f, 0x50, 0x49, 0xc9, 0x47, 0xd0, 0x70, 0x46, 0xd4, 0xf3, 0xd0, 0x1f,
- 0x62, 0xc7, 0xe8, 0x19, 0xfd, 0xd6, 0xde, 0xbd, 0xcb, 0xf3, 0xf5, 0xe5, 0xcc, 0xb8, 0x19, 0x8c,
- 0x99, 0xc4, 0x71, 0x28, 0x27, 0x56, 0x1e, 0x49, 0xb6, 0xe0, 0x56, 0x24, 0x90, 0xdb, 0xcc, 0xed,
- 0x54, 0x34, 0xa8, 0x7d, 0x79, 0xbe, 0xbe, 0xa4, 0x4c, 0x87, 0x6e, 0x01, 0xb1, 0x10, 0x5b, 0xc8,
- 0x11, 0xdc, 0xa1, 0x9e, 0x17, 0x9c, 0xd9, 0x0e, 0x47, 0x17, 0x7d, 0xc9, 0xa8, 0x27, 0x3a, 0xd5,
- 0x5e, 0xb5, 0xdf, 0xda, 0xeb, 0x5e, 0x9e, 0xaf, 0xaf, 0x6a, 0xe7, 0x7e, 0xee, 0x2b, 0xa4, 0x58,
- 0x9a, 0xf5, 0x91, 0xcf, 0xa0, 0xc5, 0x51, 0x30, 0xf5, 0x6d, 0xff, 0x84, 0x93, 0x4e, 0xad, 0x67,
- 0xf4, 0x17, 0xf7, 0xde, 0xbc, 0x3c, 0x5f, 0x5f, 0x49, 0xed, 0x47, 0x38, 0x29, 0xa4, 0x68, 0x16,
- 0xcc, 0xea, 0x28, 0xfa, 0xe4, 0xcf, 0x91, 0xb3, 0x1f, 0x99, 0x43, 0x25, 0x0b, 0xfc, 0x4e, 0xbd,
- 0x67, 0xf4, 0x1b, 0xf1, 0x51, 0x94, 0xf3, 0xbb, 0x82, 0xaf, 0x78, 0x94, 0x59, 0x9f, 0xb9, 0x01,
- 0xb5, 0x6f, 0x05, 0x72, 0xf2, 0x36, 0xbc, 0x91, 0xd2, 0x64, 0xab, 0x20, 0x5d, 0xc9, 0x86, 0xd5,
- 0x4a, 0x8d, 0x2a, 0xc8, 0xa4, 0xb0, 0x9c, 0x5f, 0x63, 0x57, 0x08, 0xe4, 0x2a, 0x07, 0x79, 0x04,
- 0x10, 0x46, 0xa7, 0x1e, 0x73, 0xf4, 0x65, 0x14, 0xb0, 0xb9, 0xb3, 0xb1, 0x9d, 0xd1, 0x7a, 0xa2,
- 0x7d, 0x47, 0x38, 0xc9, 0xb1, 0x16, 0x3e, 0x8b, 0x50, 0xc8, 0xe3, 0x50, 0xe1, 0x85, 0xd5, 0x08,
- 0xd3, 0x10, 0xf3, 0xf7, 0x0a, 0x3c, 0xb8, 0x16, 0x40, 0xd6, 0xe6, 0x38, 0x2f, 0x52, 0x7b, 0x1f,
- 0x40, 0xb2, 0x31, 0x06, 0x91, 0xb4, 0xc7, 0x42, 0xb3, 0x5b, 0xb5, 0x1a, 0x89, 0xe5, 0x1b, 0x41,
- 0x96, 0xa1, 0xce, 0x43, 0xc5, 0x7b, 0x55, 0x5f, 0xb1, 0xc6, 0xc3, 0xab, 0xf8, 0xad, 0xf5, 0xaa,
- 0xfd, 0xe6, 0x4e, 0x37, 0xbf, 0x4a, 0x7e, 0xa0, 0x03, 0x14, 0x0e, 0x67, 0xa1, 0x0c, 0x78, 0x09,
- 0xbf, 0x8f, 0x01, 0xf0, 0x85, 0x44, 0x5f, 0xf5, 0xa8, 0xd0, 0xd4, 0x34, 0x77, 0xb6, 0xf3, 0x2c,
- 0xbb, 0x91, 0x1c, 0xa9, 0xd0, 0x98, 0x82, 0x87, 0x59, 0xe4, 0xbe, 0xc7, 0xd0, 0x97, 0x87, 0x7e,
- 0x18, 0x49, 0x61, 0x15, 0x32, 0x90, 0x8d, 0x32, 0xc6, 0x17, 0xf4, 0xe9, 0xe7, 0x19, 0xfd, 0xdb,
- 0x80, 0xb7, 0x4a, 0x58, 0xb2, 0x50, 0x84, 0x81, 0x2f, 0x90, 0x10, 0xa8, 0x29, 0x01, 0x26, 0x04,
- 0xeb, 0x35, 0x59, 0x81, 0x05, 0x4e, 0xcf, 0x32, 0x2d, 0x58, 0x75, 0x4e, 0xcf, 0x0e, 0x5d, 0x72,
- 0x00, 0x8b, 0x3c, 0x81, 0xe9, 0x62, 0x35, 0x77, 0xfa, 0xa5, 0xb7, 0x08, 0xf8, 0xdc, 0x36, 0x56,
- 0x86, 0x24, 0xc7, 0x53, 0xd5, 0xa8, 0xe9, 0x3c, 0x83, 0x9b, 0x56, 0xe3, 0x38, 0x92, 0xb3, 0xe5,
- 0x30, 0x7f, 0x33, 0xa0, 0xfb, 0xea, 0xdd, 0x49, 0x1f, 0x96, 0x1c, 0x8d, 0xb7, 0x5d, 0x2a, 0xa9,
- 0xfd, 0x54, 0x04, 0x7e, 0xd2, 0x27, 0xb7, 0x63, 0xbb, 0x1a, 0x1d, 0x8f, 0x44, 0xe0, 0x93, 0x2d,
- 0x20, 0xb4, 0x98, 0x4b, 0x03, 0x92, 0x32, 0xdc, 0x99, 0xf2, 0xe8, 0x69, 0xb3, 0x06, 0x0d, 0xc1,
- 0x86, 0x3e, 0x95, 0x11, 0x8f, 0x6b, 0xd2, 0xb2, 0x72, 0x03, 0x59, 0x87, 0xa6, 0x26, 0x6a, 0x44,
- 0x7d, 0xd7, 0x43, 0x7d, 0xd7, 0x96, 0x05, 0xca, 0xf4, 0x95, 0xb6, 0x98, 0x14, 0x48, 0xce, 0xcd,
- 0x3e, 0x47, 0x7d, 0x67, 0x72, 0x54, 0x22, 0xa0, 0xcd, 0x57, 0x0a, 0x28, 0x85, 0x96, 0x28, 0xe8,
- 0x97, 0x1a, 0x98, 0xd7, 0x23, 0xae, 0x91, 0xd0, 0x26, 0x54, 0x78, 0xa8, 0xab, 0xd0, 0xdc, 0x59,
- 0xcb, 0x4f, 0x62, 0xa1, 0x37, 0x61, 0xfe, 0xf0, 0x84, 0x72, 0x39, 0x79, 0xe8, 0x4b, 0x26, 0x27,
- 0x56, 0x85, 0x87, 0xa4, 0x0f, 0x35, 0x3d, 0x33, 0xe2, 0x1e, 0x69, 0xe7, 0xf1, 0x6a, 0x6a, 0x24,
- 0x71, 0x3a, 0x82, 0x58, 0xb0, 0x92, 0x0b, 0xcc, 0x0e, 0x29, 0xa7, 0x63, 0x94, 0xc8, 0x53, 0xa9,
- 0xdd, 0x2f, 0x93, 0xda, 0x49, 0x1a, 0x65, 0xb5, 0x9d, 0x79, 0xa3, 0x98, 0x91, 0x7b, 0x7d, 0x56,
- 0xee, 0xc7, 0xb0, 0x8c, 0x2f, 0x1c, 0x2f, 0x72, 0x71, 0x4a, 0xdb, 0x0b, 0x37, 0xd2, 0x36, 0x49,
- 0xa0, 0x45, 0x75, 0xf7, 0xa0, 0x49, 0xa5, 0x44, 0x21, 0x63, 0x1d, 0xde, 0xd2, 0x3a, 0x2a, 0x9a,
- 0x66, 0xf4, 0xbf, 0xf8, 0xbf, 0xf5, 0xff, 0x3d, 0xdc, 0x9b, 0xee, 0x51, 0x81, 0x1e, 0x3a, 0x7a,
- 0xf7, 0x86, 0x4e, 0xde, 0xbb, 0x42, 0x96, 0x4f, 0xd2, 0x38, 0xeb, 0x2e, 0x2d, 0xb5, 0x9b, 0x2f,
- 0x0d, 0x58, 0x9d, 0x6f, 0x92, 0xff, 0x32, 0x2c, 0xbe, 0x9c, 0x1b, 0x16, 0xef, 0x5d, 0x35, 0x2c,
- 0xf2, 0x52, 0xbd, 0x8e, 0x71, 0xf1, 0x33, 0xf4, 0xae, 0xdb, 0xfe, 0x5f, 0xce, 0x8b, 0x3c, 0x81,
- 0x1d, 0x9c, 0x3e, 0x45, 0x47, 0x66, 0xf3, 0x22, 0xf7, 0x1c, 0x6b, 0x87, 0xf9, 0x39, 0xbc, 0x73,
- 0x13, 0xba, 0x55, 0x51, 0x69, 0xa8, 0xff, 0x4a, 0x71, 0xa9, 0xeb, 0x34, 0x0c, 0x0f, 0x5d, 0xf3,
- 0x0b, 0x78, 0xf7, 0x46, 0x17, 0x9e, 0xc1, 0x2f, 0xa6, 0xf8, 0x5f, 0x0d, 0xb8, 0x5b, 0xde, 0x11,
- 0xe4, 0x63, 0xe8, 0x4c, 0x37, 0x15, 0x95, 0x92, 0x3a, 0xa3, 0x31, 0xfa, 0x32, 0x39, 0xc3, 0x74,
- 0xd3, 0xed, 0x66, 0x6e, 0xf2, 0x3e, 0xb4, 0x39, 0x3e, 0x8b, 0x18, 0x47, 0x7b, 0xea, 0x1d, 0x53,
- 0xd1, 0x5b, 0x93, 0xc4, 0x67, 0x15, 0xde, 0x2c, 0xa5, 0x7f, 0xb0, 0xea, 0x15, 0x7f, 0xb0, 0x4f,
- 0xa0, 0x5d, 0x26, 0xc6, 0xd2, 0x66, 0xbc, 0x0d, 0x95, 0xac, 0x11, 0x2b, 0xcc, 0x35, 0x3f, 0x2d,
- 0x3e, 0x51, 0xb2, 0x21, 0x51, 0x0a, 0x5d, 0x82, 0x2a, 0xf5, 0x86, 0x1a, 0x5b, 0xb7, 0xd4, 0xd2,
- 0xfc, 0x1a, 0xc8, 0xfc, 0x84, 0x4b, 0xb6, 0x88, 0x91, 0x15, 0xe6, 0xaa, 0x5c, 0x3e, 0x1d, 0xa3,
- 0x06, 0x36, 0x2c, 0xbd, 0x56, 0x36, 0xe6, 0x64, 0x57, 0xd2, 0x6b, 0x73, 0x08, 0x90, 0xcf, 0xbf,
- 0x42, 0x96, 0xd6, 0x95, 0x59, 0x1e, 0x40, 0xcb, 0x65, 0x22, 0xf4, 0xe8, 0xc4, 0xd6, 0xbe, 0x38,
- 0x5b, 0x33, 0xb1, 0x3d, 0x2e, 0x6e, 0x54, 0xcb, 0x37, 0xda, 0xdb, 0xfb, 0xe3, 0xa2, 0x6b, 0xfc,
- 0x75, 0xd1, 0x35, 0x5e, 0x5e, 0x74, 0x8d, 0x1f, 0x3e, 0x1c, 0x32, 0x39, 0x8a, 0x4e, 0xb7, 0x9d,
- 0x60, 0x3c, 0x18, 0x72, 0xfa, 0x9c, 0xc5, 0xfd, 0x48, 0xbd, 0x41, 0xf6, 0x0e, 0xa7, 0x21, 0x9b,
- 0x79, 0x84, 0x9f, 0x2e, 0xe8, 0xc7, 0xf5, 0x07, 0xff, 0x04, 0x00, 0x00, 0xff, 0xff, 0x8f, 0xff,
- 0x0d, 0xa1, 0xad, 0x0b, 0x00, 0x00,
+ // 1073 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x56, 0x5b, 0x6f, 0x1b, 0x45,
+ 0x14, 0xd6, 0xda, 0xeb, 0xd4, 0x3e, 0x36, 0x95, 0x3b, 0x71, 0x5b, 0x53, 0x5a, 0xc7, 0x5d, 0x40,
+ 0xb2, 0xc8, 0xc5, 0x28, 0x88, 0x07, 0x28, 0x17, 0xe5, 0x52, 0x44, 0x12, 0xb5, 0x89, 0xb6, 0x02,
+ 0x09, 0x5e, 0x56, 0xe3, 0xdd, 0x83, 0x3d, 0x65, 0xbd, 0xbb, 0x9d, 0x99, 0x6d, 0x6a, 0xf1, 0x93,
+ 0x78, 0xe3, 0x89, 0x37, 0x5e, 0x91, 0x78, 0xe1, 0x17, 0x84, 0x2a, 0x8f, 0xf9, 0x15, 0x68, 0x67,
+ 0xaf, 0xb6, 0x37, 0x4d, 0x00, 0x89, 0xb7, 0xd9, 0x73, 0xce, 0x77, 0x66, 0xe6, 0x7c, 0xe7, 0x3b,
+ 0x3b, 0xb0, 0x29, 0xd1, 0xc5, 0xc0, 0xe7, 0x72, 0xe8, 0xe2, 0x98, 0xda, 0xb3, 0xa1, 0x9c, 0x05,
+ 0x28, 0x86, 0xa7, 0x38, 0xa2, 0xa1, 0x9c, 0x78, 0xd9, 0x62, 0x2b, 0xe0, 0xbe, 0xf4, 0x49, 0x3d,
+ 0xfd, 0xbe, 0xd7, 0x19, 0xfb, 0x63, 0x5f, 0x19, 0x87, 0xd1, 0x2a, 0xf6, 0x1b, 0x7f, 0x54, 0xa0,
+ 0xf9, 0x0c, 0x85, 0x60, 0xbe, 0xb7, 0x4f, 0x25, 0x25, 0x1f, 0x43, 0xc3, 0x9e, 0x50, 0xd7, 0x45,
+ 0x6f, 0x8c, 0x5d, 0xad, 0xaf, 0x0d, 0x5a, 0xbb, 0x77, 0x2f, 0xce, 0xd6, 0x56, 0x33, 0xe3, 0x86,
+ 0x3f, 0x65, 0x12, 0xa7, 0x81, 0x9c, 0x99, 0x79, 0x24, 0xd9, 0x84, 0x1b, 0xa1, 0x40, 0x6e, 0x31,
+ 0xa7, 0x5b, 0x51, 0xa0, 0xce, 0xc5, 0xd9, 0x5a, 0x3b, 0x32, 0x1d, 0x38, 0x05, 0xc4, 0x4a, 0x6c,
+ 0x21, 0x47, 0x70, 0x8b, 0xba, 0xae, 0x7f, 0x6a, 0xd9, 0x1c, 0x1d, 0xf4, 0x24, 0xa3, 0xae, 0xe8,
+ 0x56, 0xfb, 0xd5, 0x41, 0x6b, 0xb7, 0x77, 0x71, 0xb6, 0x76, 0x4f, 0x39, 0xf7, 0x72, 0x5f, 0x21,
+ 0x45, 0x7b, 0xd1, 0x47, 0x3e, 0x83, 0x16, 0x47, 0xc1, 0xa2, 0x6f, 0xeb, 0x47, 0x9c, 0x75, 0xf5,
+ 0xbe, 0x36, 0xa8, 0xef, 0xbe, 0x7d, 0x71, 0xb6, 0x76, 0x3b, 0xb5, 0x1f, 0xe1, 0xac, 0x90, 0xa2,
+ 0x59, 0x30, 0x47, 0x47, 0x51, 0x27, 0x7f, 0x89, 0x9c, 0xfd, 0xc0, 0x6c, 0x2a, 0x99, 0xef, 0x75,
+ 0x6b, 0x7d, 0x6d, 0xd0, 0x88, 0x8f, 0x12, 0x39, 0xbf, 0x2d, 0xf8, 0x8a, 0x47, 0x59, 0xf4, 0x19,
+ 0xeb, 0xa0, 0x7f, 0x23, 0x90, 0x93, 0x77, 0xe1, 0xad, 0x94, 0x26, 0x2b, 0x0a, 0x52, 0x95, 0x6c,
+ 0x98, 0xad, 0xd4, 0x18, 0x05, 0x19, 0x14, 0x56, 0xf3, 0x6b, 0xec, 0x08, 0x81, 0x3c, 0xca, 0x41,
+ 0x0e, 0x01, 0x82, 0x70, 0xe4, 0x32, 0x5b, 0x5d, 0x26, 0x02, 0x36, 0xb7, 0xd7, 0xb7, 0x32, 0x5a,
+ 0x4f, 0x94, 0xef, 0x08, 0x67, 0x39, 0xd6, 0xc4, 0x17, 0x21, 0x0a, 0x79, 0x1c, 0x44, 0x78, 0x61,
+ 0x36, 0x82, 0x34, 0xc4, 0xf8, 0xad, 0x02, 0x0f, 0xaf, 0x04, 0x90, 0xfb, 0x4b, 0x9c, 0x17, 0xa9,
+ 0x7d, 0x00, 0x20, 0xd9, 0x14, 0xfd, 0x50, 0x5a, 0x53, 0xa1, 0xd8, 0xad, 0x9a, 0x8d, 0xc4, 0xf2,
+ 0x44, 0x90, 0x55, 0xa8, 0xf1, 0x20, 0xe2, 0xbd, 0xaa, 0xae, 0xa8, 0xf3, 0xe0, 0x32, 0x7e, 0xf5,
+ 0x7e, 0x75, 0xd0, 0xdc, 0xee, 0xe5, 0x57, 0xc9, 0x0f, 0xb4, 0x8f, 0xc2, 0xe6, 0x2c, 0x90, 0x3e,
+ 0x2f, 0xe1, 0xf7, 0x29, 0x00, 0xbe, 0x92, 0xe8, 0x45, 0x3d, 0x2a, 0x14, 0x35, 0xcd, 0xed, 0xad,
+ 0x3c, 0xcb, 0x4e, 0x28, 0x27, 0x51, 0x68, 0x4c, 0xc1, 0xe3, 0x2c, 0x72, 0xcf, 0x65, 0xe8, 0xc9,
+ 0x03, 0x2f, 0x08, 0xa5, 0x30, 0x0b, 0x19, 0xc8, 0x7a, 0x19, 0xe3, 0x2b, 0xea, 0xf4, 0xcb, 0x8c,
+ 0xfe, 0xa5, 0xc1, 0x3b, 0x25, 0x2c, 0x99, 0x28, 0x02, 0xdf, 0x13, 0x48, 0x08, 0xe8, 0x91, 0x00,
+ 0x13, 0x82, 0xd5, 0x9a, 0xdc, 0x86, 0x15, 0x4e, 0x4f, 0x33, 0x2d, 0x98, 0x35, 0x4e, 0x4f, 0x0f,
+ 0x1c, 0xb2, 0x0f, 0x75, 0x9e, 0xc0, 0x54, 0xb1, 0x9a, 0xdb, 0x83, 0xd2, 0x5b, 0xf8, 0x7c, 0x69,
+ 0x1b, 0x33, 0x43, 0x92, 0xe3, 0xb9, 0x6a, 0xe8, 0x2a, 0xcf, 0xf0, 0xba, 0xd5, 0x38, 0x0e, 0xe5,
+ 0x62, 0x39, 0x8c, 0x5f, 0x35, 0xe8, 0xbd, 0x79, 0x77, 0x32, 0x80, 0xb6, 0xad, 0xf0, 0x96, 0x43,
+ 0x25, 0xb5, 0x9e, 0x0b, 0xdf, 0x4b, 0xfa, 0xe4, 0x66, 0x6c, 0x8f, 0x46, 0xc7, 0xa1, 0xf0, 0x3d,
+ 0xb2, 0x09, 0x84, 0x16, 0x73, 0x29, 0x40, 0x52, 0x86, 0x5b, 0x73, 0x1e, 0x35, 0x6d, 0xee, 0x43,
+ 0x43, 0xb0, 0xb1, 0x47, 0x65, 0xc8, 0xe3, 0x9a, 0xb4, 0xcc, 0xdc, 0x40, 0xd6, 0xa0, 0xa9, 0x88,
+ 0x9a, 0x50, 0xcf, 0x71, 0x51, 0xdd, 0xb5, 0x65, 0x42, 0x64, 0xfa, 0x5a, 0x59, 0x0c, 0x0a, 0x24,
+ 0xe7, 0x66, 0x8f, 0xa3, 0xba, 0x33, 0x39, 0x2a, 0x11, 0xd0, 0xc6, 0x1b, 0x05, 0x94, 0x42, 0x4b,
+ 0x14, 0xf4, 0xb3, 0x0e, 0xc6, 0xd5, 0x88, 0x2b, 0x24, 0xb4, 0x01, 0x15, 0x1e, 0xa8, 0x2a, 0x34,
+ 0xb7, 0xef, 0xe7, 0x27, 0x31, 0xd1, 0x9d, 0x31, 0x6f, 0x7c, 0x42, 0xb9, 0x9c, 0x3d, 0xf6, 0x24,
+ 0x93, 0x33, 0xb3, 0xc2, 0x03, 0x32, 0x00, 0x5d, 0xcd, 0x8c, 0xb8, 0x47, 0x3a, 0x79, 0x7c, 0x34,
+ 0x35, 0x92, 0x38, 0x15, 0x41, 0x4c, 0xb8, 0x9d, 0x0b, 0xcc, 0x0a, 0x28, 0xa7, 0x53, 0x94, 0xc8,
+ 0x53, 0xa9, 0x3d, 0x28, 0x93, 0xda, 0x49, 0x1a, 0x65, 0x76, 0xec, 0x65, 0xa3, 0x58, 0x90, 0x7b,
+ 0x6d, 0x51, 0xee, 0xc7, 0xb0, 0x8a, 0xaf, 0x6c, 0x37, 0x74, 0x70, 0x4e, 0xdb, 0x2b, 0xd7, 0xd2,
+ 0x36, 0x49, 0xa0, 0x45, 0x75, 0xf7, 0xa1, 0x49, 0xa5, 0x44, 0x21, 0x63, 0x1d, 0xde, 0x50, 0x3a,
+ 0x2a, 0x9a, 0x16, 0xf4, 0x5f, 0xff, 0xcf, 0xfa, 0xff, 0x0e, 0xee, 0xce, 0xf7, 0xa8, 0x40, 0x17,
+ 0x6d, 0xb5, 0x7b, 0x43, 0x25, 0xef, 0x5f, 0x22, 0xcb, 0x67, 0x69, 0x9c, 0x79, 0x87, 0x96, 0xda,
+ 0x8d, 0xd7, 0x1a, 0xdc, 0x5b, 0x6e, 0x92, 0x7f, 0x33, 0x2c, 0xbe, 0x5a, 0x1a, 0x16, 0x1f, 0x5c,
+ 0x36, 0x2c, 0xf2, 0x52, 0xfd, 0x1f, 0xe3, 0xe2, 0x27, 0xe8, 0x5f, 0xb5, 0xfd, 0x3f, 0x9c, 0x17,
+ 0x79, 0x02, 0xcb, 0x1f, 0x3d, 0x47, 0x5b, 0x66, 0xf3, 0x22, 0xf7, 0x1c, 0x2b, 0x87, 0xf1, 0x39,
+ 0xbc, 0x77, 0x1d, 0xba, 0xa3, 0xa2, 0xd2, 0x40, 0xfd, 0x95, 0xe2, 0x52, 0xd7, 0x68, 0x10, 0x1c,
+ 0x38, 0xc6, 0x17, 0xf0, 0xfe, 0xb5, 0x2e, 0xbc, 0x80, 0xaf, 0xa7, 0xf8, 0x5f, 0x34, 0xb8, 0x53,
+ 0xde, 0x11, 0xe4, 0x13, 0xe8, 0xce, 0x37, 0x15, 0x95, 0x92, 0xda, 0x93, 0x29, 0x7a, 0x32, 0x39,
+ 0xc3, 0x7c, 0xd3, 0xed, 0x64, 0x6e, 0xf2, 0x21, 0x74, 0x38, 0xbe, 0x08, 0x19, 0x47, 0x6b, 0xee,
+ 0x1d, 0x53, 0x51, 0x5b, 0x93, 0xc4, 0x67, 0x16, 0xde, 0x2c, 0xa5, 0x7f, 0xb0, 0xea, 0x25, 0x7f,
+ 0xb0, 0x4f, 0xa1, 0x53, 0x26, 0xc6, 0xd2, 0x66, 0xbc, 0x09, 0x95, 0xac, 0x11, 0x2b, 0xcc, 0x31,
+ 0x1e, 0x15, 0x9f, 0x28, 0xd9, 0x90, 0x28, 0x85, 0xb6, 0xa1, 0x4a, 0xdd, 0xb1, 0xc2, 0xd6, 0xcc,
+ 0x68, 0x69, 0xec, 0x03, 0x59, 0x9e, 0x70, 0xc9, 0x16, 0x31, 0xb2, 0xc2, 0x9c, 0x28, 0x97, 0x47,
+ 0xa7, 0xa8, 0x80, 0x0d, 0x53, 0xad, 0x0f, 0xf5, 0x7a, 0xb5, 0xad, 0x9b, 0x3a, 0xb3, 0x7d, 0xcf,
+ 0xb0, 0x00, 0xf2, 0xb9, 0x57, 0x40, 0xb7, 0x2e, 0x43, 0x93, 0x87, 0xd0, 0x72, 0x98, 0x08, 0x5c,
+ 0x3a, 0xb3, 0x94, 0x2f, 0x2e, 0x4c, 0x33, 0xb1, 0x3d, 0x8d, 0x37, 0xd0, 0xdb, 0xb5, 0x78, 0x83,
+ 0xdd, 0x27, 0xbf, 0x9f, 0xf7, 0xb4, 0x3f, 0xcf, 0x7b, 0xda, 0xeb, 0xf3, 0x9e, 0xf6, 0xfd, 0x97,
+ 0x63, 0x26, 0x27, 0xe1, 0x68, 0xcb, 0xf6, 0xa7, 0xc3, 0x31, 0xa7, 0x2f, 0x59, 0xdc, 0x7f, 0xd4,
+ 0x1d, 0x66, 0xef, 0x6e, 0x1a, 0xb0, 0x85, 0x47, 0xf7, 0xa3, 0x74, 0x11, 0x8c, 0x46, 0x2b, 0xea,
+ 0x5d, 0xfd, 0xd1, 0xdf, 0x01, 0x00, 0x00, 0xff, 0xff, 0x89, 0xb7, 0x8c, 0x49, 0xa8, 0x0b, 0x00,
+ 0x00,
}
func (m *SessionData) Marshal() (dAtA []byte, err error) {
@@ -2164,13 +2147,6 @@ func (m *RelyingPartyEntity) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i -= len(m.XXX_unrecognized)
copy(dAtA[i:], m.XXX_unrecognized)
}
- if len(m.Icon) > 0 {
- i -= len(m.Icon)
- copy(dAtA[i:], m.Icon)
- i = encodeVarintWebauthn(dAtA, i, uint64(len(m.Icon)))
- i--
- dAtA[i] = 0x1a
- }
if len(m.Name) > 0 {
i -= len(m.Name)
copy(dAtA[i:], m.Name)
@@ -2212,13 +2188,6 @@ func (m *UserEntity) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i -= len(m.XXX_unrecognized)
copy(dAtA[i:], m.XXX_unrecognized)
}
- if len(m.Icon) > 0 {
- i -= len(m.Icon)
- copy(dAtA[i:], m.Icon)
- i = encodeVarintWebauthn(dAtA, i, uint64(len(m.Icon)))
- i--
- dAtA[i] = 0x22
- }
if len(m.DisplayName) > 0 {
i -= len(m.DisplayName)
copy(dAtA[i:], m.DisplayName)
@@ -2634,10 +2603,6 @@ func (m *RelyingPartyEntity) Size() (n int) {
if l > 0 {
n += 1 + l + sovWebauthn(uint64(l))
}
- l = len(m.Icon)
- if l > 0 {
- n += 1 + l + sovWebauthn(uint64(l))
- }
if m.XXX_unrecognized != nil {
n += len(m.XXX_unrecognized)
}
@@ -2662,10 +2627,6 @@ func (m *UserEntity) Size() (n int) {
if l > 0 {
n += 1 + l + sovWebauthn(uint64(l))
}
- l = len(m.Icon)
- if l > 0 {
- n += 1 + l + sovWebauthn(uint64(l))
- }
if m.XXX_unrecognized != nil {
n += len(m.XXX_unrecognized)
}
@@ -5009,38 +4970,6 @@ func (m *RelyingPartyEntity) Unmarshal(dAtA []byte) error {
}
m.Name = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
- case 3:
- if wireType != 2 {
- return fmt.Errorf("proto: wrong wireType = %d for field Icon", wireType)
- }
- var stringLen uint64
- for shift := uint(0); ; shift += 7 {
- if shift >= 64 {
- return ErrIntOverflowWebauthn
- }
- if iNdEx >= l {
- return io.ErrUnexpectedEOF
- }
- b := dAtA[iNdEx]
- iNdEx++
- stringLen |= uint64(b&0x7F) << shift
- if b < 0x80 {
- break
- }
- }
- intStringLen := int(stringLen)
- if intStringLen < 0 {
- return ErrInvalidLengthWebauthn
- }
- postIndex := iNdEx + intStringLen
- if postIndex < 0 {
- return ErrInvalidLengthWebauthn
- }
- if postIndex > l {
- return io.ErrUnexpectedEOF
- }
- m.Icon = string(dAtA[iNdEx:postIndex])
- iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipWebauthn(dAtA[iNdEx:])
@@ -5190,38 +5119,6 @@ func (m *UserEntity) Unmarshal(dAtA []byte) error {
}
m.DisplayName = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
- case 4:
- if wireType != 2 {
- return fmt.Errorf("proto: wrong wireType = %d for field Icon", wireType)
- }
- var stringLen uint64
- for shift := uint(0); ; shift += 7 {
- if shift >= 64 {
- return ErrIntOverflowWebauthn
- }
- if iNdEx >= l {
- return io.ErrUnexpectedEOF
- }
- b := dAtA[iNdEx]
- iNdEx++
- stringLen |= uint64(b&0x7F) << shift
- if b < 0x80 {
- break
- }
- }
- intStringLen := int(stringLen)
- if intStringLen < 0 {
- return ErrInvalidLengthWebauthn
- }
- postIndex := iNdEx + intStringLen
- if postIndex < 0 {
- return ErrInvalidLengthWebauthn
- }
- if postIndex > l {
- return io.ErrUnexpectedEOF
- }
- m.Icon = string(dAtA[iNdEx:postIndex])
- iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipWebauthn(dAtA[iNdEx:])
diff --git a/lib/auth/accountrecovery_test.go b/lib/auth/accountrecovery_test.go
index 4bd5a1e651958..3b3092abfaecf 100644
--- a/lib/auth/accountrecovery_test.go
+++ b/lib/auth/accountrecovery_test.go
@@ -34,7 +34,7 @@ import (
"github.com/gravitational/teleport/api/constants"
"github.com/gravitational/teleport/api/types"
apievents "github.com/gravitational/teleport/api/types/events"
- wantypes "github.com/gravitational/teleport/api/types/webauthn"
+ wanpb "github.com/gravitational/teleport/api/types/webauthn"
"github.com/gravitational/teleport/lib/defaults"
"github.com/gravitational/teleport/lib/events"
"github.com/gravitational/teleport/lib/events/eventstest"
@@ -358,7 +358,7 @@ func TestVerifyAccountRecovery_WithAuthnErrors(t *testing.T) {
AuthnCred: &proto.VerifyAccountRecoveryRequest_MFAAuthenticateResponse{
MFAAuthenticateResponse: &proto.MFAAuthenticateResponse{
Response: &proto.MFAAuthenticateResponse_Webauthn{
- Webauthn: &wantypes.CredentialAssertionResponse{}, // invalid response
+ Webauthn: &wanpb.CredentialAssertionResponse{}, // invalid response
},
},
},
@@ -873,7 +873,7 @@ func TestCompleteAccountRecovery_WithErrors(t *testing.T) {
NewAuthnCred: &proto.CompleteAccountRecoveryRequest_NewMFAResponse{
NewMFAResponse: &proto.MFARegisterResponse{
Response: &proto.MFARegisterResponse_Webauthn{
- Webauthn: &wantypes.CredentialCreationResponse{},
+ Webauthn: &wanpb.CredentialCreationResponse{},
},
},
},
diff --git a/lib/auth/auth.go b/lib/auth/auth.go
index 7cd27cc271d41..0c1b99bcf9061 100644
--- a/lib/auth/auth.go
+++ b/lib/auth/auth.go
@@ -68,6 +68,7 @@ import (
"github.com/gravitational/teleport/lib/auth/keystore"
"github.com/gravitational/teleport/lib/auth/native"
wanlib "github.com/gravitational/teleport/lib/auth/webauthn"
+ wantypes "github.com/gravitational/teleport/lib/auth/webauthntypes"
"github.com/gravitational/teleport/lib/authz"
"github.com/gravitational/teleport/lib/backend"
"github.com/gravitational/teleport/lib/circleci"
@@ -2485,7 +2486,7 @@ func (a *Server) createRegisterChallenge(ctx context.Context, req *newRegisterCh
}
return &proto.MFARegisterChallenge{Request: &proto.MFARegisterChallenge_Webauthn{
- Webauthn: wanlib.CredentialCreationToProto(credentialCreation),
+ Webauthn: wantypes.CredentialCreationToProto(credentialCreation),
}}, nil
default:
@@ -2794,7 +2795,7 @@ func (a *Server) registerWebauthnDevice(ctx context.Context, regResp *proto.MFAR
dev, err := webRegistration.Finish(ctx, wanlib.RegisterResponse{
User: req.username,
DeviceName: req.newDeviceName,
- CreationResponse: wanlib.CredentialCreationResponseFromProto(regResp.GetWebauthn()),
+ CreationResponse: wantypes.CredentialCreationResponseFromProto(regResp.GetWebauthn()),
Passwordless: req.deviceUsage == proto.DeviceUsage_DEVICE_USAGE_PASSWORDLESS,
})
return dev, trace.Wrap(err)
@@ -4579,7 +4580,7 @@ func (a *Server) mfaAuthChallenge(ctx context.Context, user string, passwordless
return nil, trace.Wrap(err)
}
return &proto.MFAAuthenticateChallenge{
- WebauthnChallenge: wanlib.CredentialAssertionToProto(assertion),
+ WebauthnChallenge: wantypes.CredentialAssertionToProto(assertion),
}, nil
}
@@ -4611,7 +4612,7 @@ func (a *Server) mfaAuthChallenge(ctx context.Context, user string, passwordless
if err != nil {
return nil, trace.Wrap(err)
}
- challenge.WebauthnChallenge = wanlib.CredentialAssertionToProto(assertion)
+ challenge.WebauthnChallenge = wantypes.CredentialAssertionToProto(assertion)
}
return challenge, nil
@@ -4674,7 +4675,7 @@ func (a *Server) validateMFAAuthResponse(
return nil, "", trace.Wrap(err)
}
- assertionResp := wanlib.CredentialAssertionResponseFromProto(res.Webauthn)
+ assertionResp := wantypes.CredentialAssertionResponseFromProto(res.Webauthn)
var dev *types.MFADevice
if passwordless {
webLogin := &wanlib.PasswordlessFlow{
@@ -4688,7 +4689,7 @@ func (a *Server) validateMFAAuthResponse(
Webauthn: webConfig,
Identity: a.Services,
}
- dev, err = webLogin.Finish(ctx, user, wanlib.CredentialAssertionResponseFromProto(res.Webauthn))
+ dev, err = webLogin.Finish(ctx, user, wantypes.CredentialAssertionResponseFromProto(res.Webauthn))
}
if err != nil {
return nil, "", trace.AccessDenied("MFA response validation failed: %v", err)
diff --git a/lib/auth/auth_login_test.go b/lib/auth/auth_login_test.go
index 5eb4bf7fa97ab..a5a67bd0d4698 100644
--- a/lib/auth/auth_login_test.go
+++ b/lib/auth/auth_login_test.go
@@ -28,7 +28,7 @@ import (
"github.com/gravitational/teleport/api/constants"
"github.com/gravitational/teleport/api/types"
"github.com/gravitational/teleport/lib/auth/mocku2f"
- wanlib "github.com/gravitational/teleport/lib/auth/webauthn"
+ wantypes "github.com/gravitational/teleport/lib/auth/webauthntypes"
"github.com/gravitational/teleport/lib/defaults"
"github.com/gravitational/teleport/lib/services"
)
@@ -453,7 +453,7 @@ func TestServer_AuthenticateUser_mfaDevices(t *testing.T) {
switch {
case resp.GetWebauthn() != nil:
- authReq.Webauthn = wanlib.CredentialAssertionResponseFromProto(resp.GetWebauthn())
+ authReq.Webauthn = wantypes.CredentialAssertionResponseFromProto(resp.GetWebauthn())
case resp.GetTOTP() != nil:
authReq.OTP = &OTPCreds{
Password: []byte(password),
@@ -537,14 +537,14 @@ func TestServer_Authenticate_passwordless(t *testing.T) {
require.NoError(t, err)
pwdKey.SetPasswordless()
const origin = "https://localhost"
- ccr, err := pwdKey.SignCredentialCreation(origin, wanlib.CredentialCreationFromProto(registerChallenge.GetWebauthn()))
+ ccr, err := pwdKey.SignCredentialCreation(origin, wantypes.CredentialCreationFromProto(registerChallenge.GetWebauthn()))
require.NoError(t, err)
_, err = userClient.AddMFADeviceSync(ctx, &proto.AddMFADeviceSyncRequest{
TokenID: token.GetName(),
NewDeviceName: "pwdless1",
NewMFAResponse: &proto.MFARegisterResponse{
Response: &proto.MFARegisterResponse_Webauthn{
- Webauthn: wanlib.CredentialCreationResponseToProto(ccr),
+ Webauthn: wantypes.CredentialCreationResponseToProto(ccr),
},
},
})
@@ -567,11 +567,11 @@ func TestServer_Authenticate_passwordless(t *testing.T) {
tests := []struct {
name string
loginHooks []LoginHook
- authenticate func(t *testing.T, resp *wanlib.CredentialAssertionResponse)
+ authenticate func(t *testing.T, resp *wantypes.CredentialAssertionResponse)
}{
{
name: "ssh",
- authenticate: func(t *testing.T, resp *wanlib.CredentialAssertionResponse) {
+ authenticate: func(t *testing.T, resp *wantypes.CredentialAssertionResponse) {
loginResp, err := proxyClient.AuthenticateSSHUser(ctx, AuthenticateSSHRequest{
AuthenticateUserRequest: AuthenticateUserRequest{
Webauthn: resp,
@@ -591,7 +591,7 @@ func TestServer_Authenticate_passwordless(t *testing.T) {
loginHook,
loginHook,
},
- authenticate: func(t *testing.T, resp *wanlib.CredentialAssertionResponse) {
+ authenticate: func(t *testing.T, resp *wantypes.CredentialAssertionResponse) {
loginResp, err := proxyClient.AuthenticateSSHUser(ctx, AuthenticateSSHRequest{
AuthenticateUserRequest: AuthenticateUserRequest{
Webauthn: resp,
@@ -607,7 +607,7 @@ func TestServer_Authenticate_passwordless(t *testing.T) {
},
{
name: "web",
- authenticate: func(t *testing.T, resp *wanlib.CredentialAssertionResponse) {
+ authenticate: func(t *testing.T, resp *wantypes.CredentialAssertionResponse) {
session, err := proxyClient.AuthenticateWebUser(ctx, AuthenticateUserRequest{
Webauthn: resp,
})
@@ -620,7 +620,7 @@ func TestServer_Authenticate_passwordless(t *testing.T) {
loginHooks: []LoginHook{
loginHook,
},
- authenticate: func(t *testing.T, resp *wanlib.CredentialAssertionResponse) {
+ authenticate: func(t *testing.T, resp *wantypes.CredentialAssertionResponse) {
session, err := proxyClient.AuthenticateWebUser(ctx, AuthenticateUserRequest{
Webauthn: resp,
})
@@ -641,7 +641,7 @@ func TestServer_Authenticate_passwordless(t *testing.T) {
_, err := proxyClient.AuthenticateSSHUser(ctx, AuthenticateSSHRequest{
AuthenticateUserRequest: AuthenticateUserRequest{
Username: user,
- Webauthn: &wanlib.CredentialAssertionResponse{}, // bad response
+ Webauthn: &wantypes.CredentialAssertionResponse{}, // bad response
PublicKey: []byte(sshPubKey),
},
TTL: 24 * time.Hour,
@@ -660,7 +660,7 @@ func TestServer_Authenticate_passwordless(t *testing.T) {
require.NoError(t, err, "Failed to create passwordless challenge")
// Sign challenge (mocks user interaction).
- assertionResp, err := pwdKey.SignAssertion(origin, wanlib.CredentialAssertionFromProto(mfaChallenge.GetWebauthnChallenge()))
+ assertionResp, err := pwdKey.SignAssertion(origin, wantypes.CredentialAssertionFromProto(mfaChallenge.GetWebauthnChallenge()))
require.NoError(t, err)
assertionResp.AssertionResponse.UserHandle = userWebID // identify user, a real device would set this
@@ -727,7 +727,7 @@ func TestServer_Authenticate_nonPasswordlessRequiresUsername(t *testing.T) {
}
switch {
case mfaResp.GetWebauthn() != nil:
- req.Webauthn = wanlib.CredentialAssertionResponseFromProto(mfaResp.GetWebauthn())
+ req.Webauthn = wantypes.CredentialAssertionResponseFromProto(mfaResp.GetWebauthn())
case mfaResp.GetTOTP() != nil:
req.OTP = &OTPCreds{
Password: []byte(password),
@@ -813,7 +813,7 @@ func TestServer_Authenticate_headless(t *testing.T) {
_, err = proxyClient.AuthenticateSSHUser(ctx, AuthenticateSSHRequest{
AuthenticateUserRequest: AuthenticateUserRequest{
Username: username,
- Webauthn: &wanlib.CredentialAssertionResponse{}, // bad response
+ Webauthn: &wantypes.CredentialAssertionResponse{}, // bad response
PublicKey: []byte(sshPubKey),
},
TTL: 24 * time.Hour,
@@ -857,7 +857,7 @@ func TestServer_Authenticate_headless(t *testing.T) {
AuthenticateUserRequest: AuthenticateUserRequest{
// HeadlessAuthenticationID should take precedence over WebAuthn and OTP fields.
HeadlessAuthenticationID: headlessID,
- Webauthn: &wanlib.CredentialAssertionResponse{},
+ Webauthn: &wantypes.CredentialAssertionResponse{},
OTP: &OTPCreds{},
Username: username,
PublicKey: []byte(sshPubKey),
diff --git a/lib/auth/auth_with_roles_test.go b/lib/auth/auth_with_roles_test.go
index fc4ded1b8d385..1de6cedae5f61 100644
--- a/lib/auth/auth_with_roles_test.go
+++ b/lib/auth/auth_with_roles_test.go
@@ -44,7 +44,7 @@ import (
"github.com/gravitational/teleport/api/types"
apievents "github.com/gravitational/teleport/api/types/events"
"github.com/gravitational/teleport/api/types/installers"
- "github.com/gravitational/teleport/api/types/webauthn"
+ wanpb "github.com/gravitational/teleport/api/types/webauthn"
"github.com/gravitational/teleport/api/types/wrappers"
apiutils "github.com/gravitational/teleport/api/utils"
"github.com/gravitational/teleport/api/utils/sshutils"
@@ -4881,7 +4881,7 @@ func TestUpdateHeadlessAuthenticationState(t *testing.T) {
// default to failed mfa challenge response
resp := &proto.MFAAuthenticateResponse{
Response: &proto.MFAAuthenticateResponse_Webauthn{
- Webauthn: &webauthn.CredentialAssertionResponse{
+ Webauthn: &wanpb.CredentialAssertionResponse{
Type: "bad response",
},
},
diff --git a/lib/auth/grpcserver_test.go b/lib/auth/grpcserver_test.go
index b8d6ed6555dcb..cc5f432e59064 100644
--- a/lib/auth/grpcserver_test.go
+++ b/lib/auth/grpcserver_test.go
@@ -61,7 +61,7 @@ import (
"github.com/gravitational/teleport/api/utils/sshutils"
"github.com/gravitational/teleport/lib/auth/mocku2f"
"github.com/gravitational/teleport/lib/auth/testauthority"
- wanlib "github.com/gravitational/teleport/lib/auth/webauthn"
+ wantypes "github.com/gravitational/teleport/lib/auth/webauthntypes"
"github.com/gravitational/teleport/lib/authz"
"github.com/gravitational/teleport/lib/defaults"
"github.com/gravitational/teleport/lib/modules"
@@ -177,12 +177,12 @@ func TestMFADeviceManagement(t *testing.T) {
authHandler: devs.webAuthHandler,
checkAuthErr: require.NoError,
registerHandler: func(t *testing.T, challenge *proto.MFARegisterChallenge) *proto.MFARegisterResponse {
- ccr, err := webKey2.SignCredentialCreation(webOrigin, wanlib.CredentialCreationFromProto(challenge.GetWebauthn()))
+ ccr, err := webKey2.SignCredentialCreation(webOrigin, wantypes.CredentialCreationFromProto(challenge.GetWebauthn()))
require.NoError(t, err)
return &proto.MFARegisterResponse{
Response: &proto.MFARegisterResponse_Webauthn{
- Webauthn: wanlib.CredentialCreationResponseToProto(ccr),
+ Webauthn: wantypes.CredentialCreationResponseToProto(ccr),
},
}
},
@@ -204,11 +204,11 @@ func TestMFADeviceManagement(t *testing.T) {
require.NoError(t, err)
key.PreferRPID = true
key.IgnoreAllowedCredentials = true
- resp, err := key.SignAssertion(webOrigin, wanlib.CredentialAssertionFromProto(challenge.WebauthnChallenge))
+ resp, err := key.SignAssertion(webOrigin, wantypes.CredentialAssertionFromProto(challenge.WebauthnChallenge))
require.NoError(t, err)
return &proto.MFAAuthenticateResponse{
Response: &proto.MFAAuthenticateResponse_Webauthn{
- Webauthn: wanlib.CredentialAssertionResponseToProto(resp),
+ Webauthn: wantypes.CredentialAssertionResponseToProto(resp),
},
}
},
@@ -235,11 +235,11 @@ func TestMFADeviceManagement(t *testing.T) {
key.PreferRPID = true
ccr, err := key.SignCredentialCreation(
- "http://badorigin.com" /* origin */, wanlib.CredentialCreationFromProto(challenge.GetWebauthn()))
+ "http://badorigin.com" /* origin */, wantypes.CredentialCreationFromProto(challenge.GetWebauthn()))
require.NoError(t, err)
return &proto.MFARegisterResponse{
Response: &proto.MFARegisterResponse_Webauthn{
- Webauthn: wanlib.CredentialCreationResponseToProto(ccr),
+ Webauthn: wantypes.CredentialCreationResponseToProto(ccr),
},
}
},
@@ -267,12 +267,12 @@ func TestMFADeviceManagement(t *testing.T) {
key.PreferRPID = true
key.SetPasswordless()
- ccr, err := key.SignCredentialCreation(webOrigin, wanlib.CredentialCreationFromProto(challenge.GetWebauthn()))
+ ccr, err := key.SignCredentialCreation(webOrigin, wantypes.CredentialCreationFromProto(challenge.GetWebauthn()))
require.NoError(t, err)
return &proto.MFARegisterResponse{
Response: &proto.MFARegisterResponse_Webauthn{
- Webauthn: wanlib.CredentialCreationResponseToProto(ccr),
+ Webauthn: wantypes.CredentialCreationResponseToProto(ccr),
},
}
},
@@ -355,11 +355,11 @@ func TestMFADeviceManagement(t *testing.T) {
require.NoError(t, err)
key.PreferRPID = true
key.IgnoreAllowedCredentials = true
- resp, err := key.SignAssertion(webOrigin, wanlib.CredentialAssertionFromProto(challenge.WebauthnChallenge))
+ resp, err := key.SignAssertion(webOrigin, wantypes.CredentialAssertionFromProto(challenge.WebauthnChallenge))
require.NoError(t, err)
return &proto.MFAAuthenticateResponse{
Response: &proto.MFAAuthenticateResponse_Webauthn{
- Webauthn: wanlib.CredentialAssertionResponseToProto(resp),
+ Webauthn: wantypes.CredentialAssertionResponseToProto(resp),
},
}
},
@@ -404,11 +404,11 @@ func TestMFADeviceManagement(t *testing.T) {
},
authHandler: func(t *testing.T, challenge *proto.MFAAuthenticateChallenge) *proto.MFAAuthenticateResponse {
resp, err := webKey2.SignAssertion(
- webOrigin, wanlib.CredentialAssertionFromProto(challenge.WebauthnChallenge))
+ webOrigin, wantypes.CredentialAssertionFromProto(challenge.WebauthnChallenge))
require.NoError(t, err)
return &proto.MFAAuthenticateResponse{
Response: &proto.MFAAuthenticateResponse_Webauthn{
- Webauthn: wanlib.CredentialAssertionResponseToProto(resp),
+ Webauthn: wantypes.CredentialAssertionResponseToProto(resp),
},
}
},
@@ -458,11 +458,11 @@ func (d *mfaDevices) webAuthHandler(t *testing.T, challenge *proto.MFAAuthentica
require.NotNil(t, challenge.WebauthnChallenge)
resp, err := d.WebKey.SignAssertion(
- d.webOrigin, wanlib.CredentialAssertionFromProto(challenge.WebauthnChallenge))
+ d.webOrigin, wantypes.CredentialAssertionFromProto(challenge.WebauthnChallenge))
require.NoError(t, err)
return &proto.MFAAuthenticateResponse{
Response: &proto.MFAAuthenticateResponse_Webauthn{
- Webauthn: wanlib.CredentialAssertionResponseToProto(resp),
+ Webauthn: wantypes.CredentialAssertionResponseToProto(resp),
},
}
}
@@ -541,11 +541,11 @@ func addOneOfEachMFADevice(t *testing.T, cl *Client, clock clockwork.Clock, orig
registerHandler: func(t *testing.T, challenge *proto.MFARegisterChallenge) *proto.MFARegisterResponse {
require.NotNil(t, challenge.GetWebauthn())
- ccr, err := mfaDevs.WebKey.SignCredentialCreation(origin, wanlib.CredentialCreationFromProto(challenge.GetWebauthn()))
+ ccr, err := mfaDevs.WebKey.SignCredentialCreation(origin, wantypes.CredentialCreationFromProto(challenge.GetWebauthn()))
require.NoError(t, err)
return &proto.MFARegisterResponse{
Response: &proto.MFARegisterResponse_Webauthn{
- Webauthn: wanlib.CredentialCreationResponseToProto(ccr),
+ Webauthn: wantypes.CredentialCreationResponseToProto(ccr),
},
}
},
diff --git a/lib/auth/helpers_mfa.go b/lib/auth/helpers_mfa.go
index e1e2ae09ff45e..c021bb399679a 100644
--- a/lib/auth/helpers_mfa.go
+++ b/lib/auth/helpers_mfa.go
@@ -28,7 +28,7 @@ import (
"github.com/gravitational/teleport/api/client/proto"
"github.com/gravitational/teleport/api/types"
"github.com/gravitational/teleport/lib/auth/mocku2f"
- wanlib "github.com/gravitational/teleport/lib/auth/webauthn"
+ wantypes "github.com/gravitational/teleport/lib/auth/webauthntypes"
)
// TestDevice is a test MFA device.
@@ -178,13 +178,13 @@ func (d *TestDevice) solveAuthnKey(c *proto.MFAAuthenticateChallenge) (*proto.MF
if c.WebauthnChallenge == nil {
return nil, trace.BadParameter("key-based challenge not present")
}
- resp, err := d.Key.SignAssertion(d.Origin(), wanlib.CredentialAssertionFromProto(c.WebauthnChallenge))
+ resp, err := d.Key.SignAssertion(d.Origin(), wantypes.CredentialAssertionFromProto(c.WebauthnChallenge))
if err != nil {
return nil, trace.Wrap(err)
}
return &proto.MFAAuthenticateResponse{
Response: &proto.MFAAuthenticateResponse_Webauthn{
- Webauthn: wanlib.CredentialAssertionResponseToProto(resp),
+ Webauthn: wantypes.CredentialAssertionResponseToProto(resp),
},
}, nil
}
@@ -238,13 +238,13 @@ func (d *TestDevice) solveRegisterWebauthn(c *proto.MFARegisterChallenge) (*prot
d.Key.SetUV = true
}
- resp, err := d.Key.SignCredentialCreation(d.Origin(), wanlib.CredentialCreationFromProto(c.GetWebauthn()))
+ resp, err := d.Key.SignCredentialCreation(d.Origin(), wantypes.CredentialCreationFromProto(c.GetWebauthn()))
if err != nil {
return nil, trace.Wrap(err)
}
return &proto.MFARegisterResponse{
Response: &proto.MFARegisterResponse_Webauthn{
- Webauthn: wanlib.CredentialCreationResponseToProto(resp),
+ Webauthn: wantypes.CredentialCreationResponseToProto(resp),
},
}, nil
}
diff --git a/lib/auth/httpfallback.go b/lib/auth/httpfallback.go
index d969bf02fbce5..69b34773ab93d 100644
--- a/lib/auth/httpfallback.go
+++ b/lib/auth/httpfallback.go
@@ -22,7 +22,7 @@ import (
"github.com/gravitational/trace"
"github.com/gravitational/teleport/api/client/proto"
- wanlib "github.com/gravitational/teleport/lib/auth/webauthn"
+ wantypes "github.com/gravitational/teleport/lib/auth/webauthntypes"
)
// httpfallback.go holds endpoints that have been converted to gRPC
@@ -39,7 +39,7 @@ type legacyChangePasswordReq struct {
// SecondFactorToken is user 2nd factor token
SecondFactorToken string `json:"second_factor_token"`
// WebauthnResponse is Webauthn sign response
- WebauthnResponse *wanlib.CredentialAssertionResponse `json:"webauthn_response"`
+ WebauthnResponse *wantypes.CredentialAssertionResponse `json:"webauthn_response"`
}
// ChangePassword updates users password based on the old password.
@@ -57,7 +57,7 @@ func (c *Client) ChangePassword(ctx context.Context, req *proto.ChangePasswordRe
OldPassword: req.OldPassword,
NewPassword: req.NewPassword,
SecondFactorToken: req.SecondFactorToken,
- WebauthnResponse: wanlib.CredentialAssertionResponseFromProto(req.Webauthn),
+ WebauthnResponse: wantypes.CredentialAssertionResponseFromProto(req.Webauthn),
})
return trace.Wrap(err)
}
diff --git a/lib/auth/methods.go b/lib/auth/methods.go
index 5302a06bd464d..8fc43112d7c4e 100644
--- a/lib/auth/methods.go
+++ b/lib/auth/methods.go
@@ -30,7 +30,7 @@ import (
"github.com/gravitational/teleport/api/types"
apievents "github.com/gravitational/teleport/api/types/events"
"github.com/gravitational/teleport/api/utils/keys"
- wanlib "github.com/gravitational/teleport/lib/auth/webauthn"
+ wantypes "github.com/gravitational/teleport/lib/auth/webauthntypes"
"github.com/gravitational/teleport/lib/defaults"
"github.com/gravitational/teleport/lib/events"
"github.com/gravitational/teleport/lib/services"
@@ -57,7 +57,7 @@ type AuthenticateUserRequest struct {
// Pass is a password used in local authentication schemes
Pass *PassCreds `json:"pass,omitempty"`
// Webauthn is a signed credential assertion, used in MFA authentication
- Webauthn *wanlib.CredentialAssertionResponse `json:"webauthn,omitempty"`
+ Webauthn *wantypes.CredentialAssertionResponse `json:"webauthn,omitempty"`
// OTP is a password and second factor, used for MFA authentication
OTP *OTPCreds `json:"otp,omitempty"`
// Session is a web session credential used to authenticate web sessions
@@ -233,7 +233,7 @@ func (s *Server) authenticateUser(ctx context.Context, req AuthenticateUserReque
authenticateFn = func() (*types.MFADevice, error) {
mfaResponse := &proto.MFAAuthenticateResponse{
Response: &proto.MFAAuthenticateResponse_Webauthn{
- Webauthn: wanlib.CredentialAssertionResponseToProto(req.Webauthn),
+ Webauthn: wantypes.CredentialAssertionResponseToProto(req.Webauthn),
},
}
dev, _, err := s.validateMFAAuthResponse(ctx, mfaResponse, user, passwordless)
@@ -327,7 +327,7 @@ func (s *Server) authenticateUser(ctx context.Context, req AuthenticateUserReque
func (s *Server) authenticatePasswordless(ctx context.Context, req AuthenticateUserRequest) (*types.MFADevice, string, error) {
mfaResponse := &proto.MFAAuthenticateResponse{
Response: &proto.MFAAuthenticateResponse_Webauthn{
- Webauthn: wanlib.CredentialAssertionResponseToProto(req.Webauthn),
+ Webauthn: wantypes.CredentialAssertionResponseToProto(req.Webauthn),
},
}
dev, user, err := s.validateMFAAuthResponse(ctx, mfaResponse, "", true /* passwordless */)
diff --git a/lib/auth/mocku2f/webauthn.go b/lib/auth/mocku2f/webauthn.go
index 833e1c82a3087..03faeb31c0d51 100644
--- a/lib/auth/mocku2f/webauthn.go
+++ b/lib/auth/mocku2f/webauthn.go
@@ -30,11 +30,12 @@ import (
wanlib "github.com/gravitational/teleport/lib/auth/webauthn"
wancli "github.com/gravitational/teleport/lib/auth/webauthncli"
+ wantypes "github.com/gravitational/teleport/lib/auth/webauthntypes"
)
// SignAssertion signs a WebAuthn assertion following the
// U2F-compat-getAssertion algorithm.
-func (muk *Key) SignAssertion(origin string, assertion *wanlib.CredentialAssertion) (*wanlib.CredentialAssertionResponse, error) {
+func (muk *Key) SignAssertion(origin string, assertion *wantypes.CredentialAssertion) (*wantypes.CredentialAssertionResponse, error) {
// Reference:
// https://fidoalliance.org/specs/fido-v2.1-ps-20210615/fido-client-to-authenticator-protocol-v2.1-ps-20210615.html#u2f-authenticatorGetAssertion-interoperability
@@ -52,7 +53,7 @@ func (muk *Key) SignAssertion(origin string, assertion *wanlib.CredentialAsserti
// Use RPID or App ID?
appID := assertion.Response.RelyingPartyID
- if value, ok := assertion.Response.Extensions[wanlib.AppIDExtension]; !muk.PreferRPID && ok {
+ if value, ok := assertion.Response.Extensions[wantypes.AppIDExtension]; !muk.PreferRPID && ok {
if appID, ok = value.(string); !ok {
return nil, trace.BadParameter("u2f app ID has unexpected type: %T", value)
}
@@ -76,9 +77,9 @@ func (muk *Key) SignAssertion(origin string, assertion *wanlib.CredentialAsserti
return nil, trace.Wrap(err)
}
- return &wanlib.CredentialAssertionResponse{
- PublicKeyCredential: wanlib.PublicKeyCredential{
- Credential: wanlib.Credential{
+ return &wantypes.CredentialAssertionResponse{
+ PublicKeyCredential: wantypes.PublicKeyCredential{
+ Credential: wantypes.Credential{
ID: base64.RawURLEncoding.EncodeToString(muk.KeyHandle),
Type: string(protocol.PublicKeyCredentialType),
},
@@ -86,8 +87,8 @@ func (muk *Key) SignAssertion(origin string, assertion *wanlib.CredentialAsserti
// Mimic browsers and don't set the output AppID extension, even if we
// used it.
},
- AssertionResponse: wanlib.AuthenticatorAssertionResponse{
- AuthenticatorResponse: wanlib.AuthenticatorResponse{
+ AssertionResponse: wantypes.AuthenticatorAssertionResponse{
+ AuthenticatorResponse: wantypes.AuthenticatorResponse{
ClientDataJSON: ccd,
},
AuthenticatorData: res.AuthData,
@@ -99,7 +100,7 @@ func (muk *Key) SignAssertion(origin string, assertion *wanlib.CredentialAsserti
// SignCredentialCreation signs a WebAuthn credential creation request following
// the U2F-compat-makeCredential algorithm.
-func (muk *Key) SignCredentialCreation(origin string, cc *wanlib.CredentialCreation) (*wanlib.CredentialCreationResponse, error) {
+func (muk *Key) SignCredentialCreation(origin string, cc *wantypes.CredentialCreation) (*wantypes.CredentialCreationResponse, error) {
// Reference:
// https: // fidoalliance.org/specs/fido-v2.1-ps-20210615/fido-client-to-authenticator-protocol-v2.1-ps-20210615.html#fig-u2f-compat-makeCredential
@@ -181,16 +182,16 @@ func (muk *Key) SignCredentialCreation(origin string, cc *wanlib.CredentialCreat
return nil, trace.Wrap(err)
}
- return &wanlib.CredentialCreationResponse{
- PublicKeyCredential: wanlib.PublicKeyCredential{
- Credential: wanlib.Credential{
+ return &wantypes.CredentialCreationResponse{
+ PublicKeyCredential: wantypes.PublicKeyCredential{
+ Credential: wantypes.Credential{
ID: base64.RawURLEncoding.EncodeToString(muk.KeyHandle),
Type: string(protocol.PublicKeyCredentialType),
},
RawID: muk.KeyHandle,
},
- AttestationResponse: wanlib.AuthenticatorAttestationResponse{
- AuthenticatorResponse: wanlib.AuthenticatorResponse{
+ AttestationResponse: wantypes.AuthenticatorAttestationResponse{
+ AuthenticatorResponse: wantypes.AuthenticatorResponse{
ClientDataJSON: ccd,
},
AttestationObject: attObj,
diff --git a/lib/auth/password.go b/lib/auth/password.go
index 02bacd190fbdc..bb02160d39e09 100644
--- a/lib/auth/password.go
+++ b/lib/auth/password.go
@@ -30,7 +30,7 @@ import (
"github.com/gravitational/teleport/api/types"
apievents "github.com/gravitational/teleport/api/types/events"
"github.com/gravitational/teleport/api/utils/keys"
- wanlib "github.com/gravitational/teleport/lib/auth/webauthn"
+ wantypes "github.com/gravitational/teleport/lib/auth/webauthntypes"
"github.com/gravitational/teleport/lib/authz"
"github.com/gravitational/teleport/lib/defaults"
"github.com/gravitational/teleport/lib/events"
@@ -123,7 +123,7 @@ func (s *Server) ChangePassword(ctx context.Context, req *proto.ChangePasswordRe
user := req.User
authReq := AuthenticateUserRequest{
Username: user,
- Webauthn: wanlib.CredentialAssertionResponseFromProto(req.Webauthn),
+ Webauthn: wantypes.CredentialAssertionResponseFromProto(req.Webauthn),
}
if len(req.OldPassword) > 0 {
authReq.Pass = &PassCreds{
diff --git a/lib/auth/password_test.go b/lib/auth/password_test.go
index 1211bef28a6e6..f05003dbb42d5 100644
--- a/lib/auth/password_test.go
+++ b/lib/auth/password_test.go
@@ -33,7 +33,7 @@ import (
"github.com/gravitational/teleport/api/constants"
"github.com/gravitational/teleport/api/types"
apievents "github.com/gravitational/teleport/api/types/events"
- wantypes "github.com/gravitational/teleport/api/types/webauthn"
+ wanpb "github.com/gravitational/teleport/api/types/webauthn"
"github.com/gravitational/teleport/lib/auth/keystore"
authority "github.com/gravitational/teleport/lib/auth/testauthority"
"github.com/gravitational/teleport/lib/backend"
@@ -312,7 +312,7 @@ func TestChangeUserAuthentication(t *testing.T) {
TokenID: resetTokenID,
NewPassword: []byte("password2"),
NewMFARegisterResponse: &proto.MFARegisterResponse{Response: &proto.MFARegisterResponse_Webauthn{
- Webauthn: &wantypes.CredentialCreationResponse{},
+ Webauthn: &wanpb.CredentialCreationResponse{},
}},
}
},
diff --git a/lib/auth/touchid/api.go b/lib/auth/touchid/api.go
index 5745593b6c370..5e00e8da914b4 100644
--- a/lib/auth/touchid/api.go
+++ b/lib/auth/touchid/api.go
@@ -36,7 +36,7 @@ import (
"github.com/gravitational/trace"
log "github.com/sirupsen/logrus"
- wanlib "github.com/gravitational/teleport/lib/auth/webauthn"
+ wantypes "github.com/gravitational/teleport/lib/auth/webauthntypes"
"github.com/gravitational/teleport/lib/darwin"
)
@@ -185,7 +185,7 @@ func Diag() (*DiagResult, error) {
// Confirm may replace equivalent keys with the new key, at the implementation's
// discretion.
type Registration struct {
- CCR *wanlib.CredentialCreationResponse
+ CCR *wantypes.CredentialCreationResponse
credentialID string
@@ -217,7 +217,7 @@ func (r *Registration) Rollback() error {
// Callers are encouraged to either explicitly Confirm or Rollback the returned
// registration.
// See Registration.
-func Register(origin string, cc *wanlib.CredentialCreation) (*Registration, error) {
+func Register(origin string, cc *wantypes.CredentialCreation) (*Registration, error) {
if !IsAvailable() {
return nil, ErrNotAvailable
}
@@ -319,16 +319,16 @@ func Register(origin string, cc *wanlib.CredentialCreation) (*Registration, erro
return nil, trace.Wrap(err)
}
- ccr := &wanlib.CredentialCreationResponse{
- PublicKeyCredential: wanlib.PublicKeyCredential{
- Credential: wanlib.Credential{
+ ccr := &wantypes.CredentialCreationResponse{
+ PublicKeyCredential: wantypes.PublicKeyCredential{
+ Credential: wantypes.Credential{
ID: credentialID,
Type: string(protocol.PublicKeyCredentialType),
},
RawID: []byte(credentialID),
},
- AttestationResponse: wanlib.AuthenticatorAttestationResponse{
- AuthenticatorResponse: wanlib.AuthenticatorResponse{
+ AttestationResponse: wantypes.AuthenticatorAttestationResponse{
+ AuthenticatorResponse: wantypes.AuthenticatorResponse{
ClientDataJSON: attData.ccdJSON,
},
AttestationObject: attObj,
@@ -433,7 +433,7 @@ type CredentialPicker interface {
// Login authenticates using a Secure Enclave-backed biometric credential.
// It returns the assertion response and the user that owns the credential to
// sign it.
-func Login(origin, user string, assertion *wanlib.CredentialAssertion, picker CredentialPicker) (*wanlib.CredentialAssertionResponse, string, error) {
+func Login(origin, user string, assertion *wantypes.CredentialAssertion, picker CredentialPicker) (*wantypes.CredentialAssertionResponse, string, error) {
if !IsAvailable() {
return nil, "", ErrNotAvailable
}
@@ -503,16 +503,16 @@ func Login(origin, user string, assertion *wanlib.CredentialAssertion, picker Cr
return nil, "", trace.Wrap(err)
}
- return &wanlib.CredentialAssertionResponse{
- PublicKeyCredential: wanlib.PublicKeyCredential{
- Credential: wanlib.Credential{
+ return &wantypes.CredentialAssertionResponse{
+ PublicKeyCredential: wantypes.PublicKeyCredential{
+ Credential: wantypes.Credential{
ID: cred.CredentialID,
Type: string(protocol.PublicKeyCredentialType),
},
RawID: []byte(cred.CredentialID),
},
- AssertionResponse: wanlib.AuthenticatorAssertionResponse{
- AuthenticatorResponse: wanlib.AuthenticatorResponse{
+ AssertionResponse: wantypes.AuthenticatorAssertionResponse{
+ AuthenticatorResponse: wantypes.AuthenticatorResponse{
ClientDataJSON: attData.ccdJSON,
},
AuthenticatorData: attData.rawAuthData,
@@ -524,7 +524,7 @@ func Login(origin, user string, assertion *wanlib.CredentialAssertion, picker Cr
func pickCredential(
actx AuthContext,
- infos []CredentialInfo, allowedCredentials []protocol.CredentialDescriptor,
+ infos []CredentialInfo, allowedCredentials []wantypes.CredentialDescriptor,
picker CredentialPicker, promptOnce func(), userRequested bool,
) (*CredentialInfo, error) {
// Handle early exits.
diff --git a/lib/auth/touchid/api_test.go b/lib/auth/touchid/api_test.go
index 5e73000e48f8c..459121b382ba6 100644
--- a/lib/auth/touchid/api_test.go
+++ b/lib/auth/touchid/api_test.go
@@ -35,7 +35,7 @@ import (
"github.com/stretchr/testify/require"
"github.com/gravitational/teleport/lib/auth/touchid"
- wanlib "github.com/gravitational/teleport/lib/auth/webauthn"
+ wantypes "github.com/gravitational/teleport/lib/auth/webauthntypes"
)
func init() {
@@ -68,14 +68,14 @@ func TestRegisterAndLogin(t *testing.T) {
name string
webUser *fakeUser
origin, user string
- modifyAssertion func(a *wanlib.CredentialAssertion)
+ modifyAssertion func(a *wantypes.CredentialAssertion)
wantUser string
}{
{
name: "passwordless",
webUser: &fakeUser{id: []byte{1, 2, 3, 4, 5}, name: llamaUser},
origin: web.Config.RPOrigin,
- modifyAssertion: func(a *wanlib.CredentialAssertion) {
+ modifyAssertion: func(a *wantypes.CredentialAssertion) {
a.Response.AllowedCredentials = nil // aka passwordless
},
wantUser: llamaUser,
@@ -94,7 +94,7 @@ func TestRegisterAndLogin(t *testing.T) {
cc, sessionData, err := web.BeginRegistration(webUser)
require.NoError(t, err)
- reg, err := touchid.Register(origin, (*wanlib.CredentialCreation)(cc))
+ reg, err := touchid.Register(origin, wantypes.CredentialCreationFromProtocol(cc))
require.NoError(t, err, "Register failed")
assert.Equal(t, 1, fake.userPrompts, "unexpected number of Registration prompts")
@@ -116,7 +116,7 @@ func TestRegisterAndLogin(t *testing.T) {
// Login section.
a, sessionData, err := web.BeginLogin(webUser)
require.NoError(t, err, "BeginLogin failed")
- assertion := (*wanlib.CredentialAssertion)(a)
+ assertion := wantypes.CredentialAssertionFromProtocol(a)
test.modifyAssertion(assertion)
assertionResp, actualUser, err := touchid.Login(origin, user, assertion, simplePicker{})
@@ -162,7 +162,7 @@ func TestRegister_rollback(t *testing.T) {
require.NoError(t, err)
// Register and then Rollback a credential.
- reg, err := touchid.Register(origin, (*wanlib.CredentialCreation)(cc))
+ reg, err := touchid.Register(origin, wantypes.CredentialCreationFromProtocol(cc))
require.NoError(t, err, "Register failed")
require.NoError(t, reg.Rollback(), "Rollback failed")
@@ -170,8 +170,8 @@ func TestRegister_rollback(t *testing.T) {
require.Contains(t, fake.nonInteractiveDelete, reg.CCR.ID, "Credential ID not found in (fake) nonInteractiveDeletes")
// Attempt to authenticate.
- _, _, err = touchid.Login(origin, llamaUser, &wanlib.CredentialAssertion{
- Response: protocol.PublicKeyCredentialRequestOptions{
+ _, _, err = touchid.Login(origin, llamaUser, &wantypes.CredentialAssertion{
+ Response: wantypes.PublicKeyCredentialRequestOptions{
Challenge: []byte{1, 2, 3, 4, 5}, // doesn't matter as long as it's not empty
RelyingPartyID: web.Config.RPID,
UserVerification: "required",
@@ -225,7 +225,7 @@ func TestLogin_findsCorrectCredential(t *testing.T) {
cc, _, err := web.BeginRegistration(u)
require.NoError(t, err, "BeginRegistration #%v failed, user %v", i+1, u.name)
- reg, err := touchid.Register(origin, (*wanlib.CredentialCreation)(cc))
+ reg, err := touchid.Register(origin, wantypes.CredentialCreationFromProtocol(cc))
require.NoError(t, err, "Register #%v failed, user %v", i+1, u.name)
require.NoError(t, reg.Confirm(), "Confirm failed")
}
@@ -243,7 +243,7 @@ func TestLogin_findsCorrectCredential(t *testing.T) {
cc, _, err := web2.BeginRegistration(u)
require.NoError(t, err, "web2 BeginRegistration failed")
- reg, err := touchid.Register(web2.Config.RPOrigin, (*wanlib.CredentialCreation)(cc))
+ reg, err := touchid.Register(web2.Config.RPOrigin, wantypes.CredentialCreationFromProtocol(cc))
require.NoError(t, err, "web2 Register failed")
require.NoError(t, reg.Confirm(), "Confirm failed")
}
@@ -324,16 +324,16 @@ func TestLogin_findsCorrectCredential(t *testing.T) {
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
- var allowedCreds []protocol.CredentialDescriptor
+ var allowedCreds []wantypes.CredentialDescriptor
for _, cred := range test.allowedCreds {
- allowedCreds = append(allowedCreds, protocol.CredentialDescriptor{
+ allowedCreds = append(allowedCreds, wantypes.CredentialDescriptor{
Type: protocol.PublicKeyCredentialType,
CredentialID: []byte(cred.id),
})
}
- _, gotUser, err := touchid.Login(origin, test.user, &wanlib.CredentialAssertion{
- Response: protocol.PublicKeyCredentialRequestOptions{
+ _, gotUser, err := touchid.Login(origin, test.user, &wantypes.CredentialAssertion{
+ Response: wantypes.PublicKeyCredentialRequestOptions{
Challenge: []byte{1, 2, 3, 4, 5}, // arbitrary
RelyingPartyID: web.Config.RPID,
AllowedCredentials: allowedCreds,
@@ -361,8 +361,8 @@ func TestLogin_noCredentials_failsWithoutUserInteraction(t *testing.T) {
*touchid.Native = fake
const origin = "https://goteleport.com"
- baseAssertion := &wanlib.CredentialAssertion{
- Response: protocol.PublicKeyCredentialRequestOptions{
+ baseAssertion := &wantypes.CredentialAssertion{
+ Response: wantypes.PublicKeyCredentialRequestOptions{
Challenge: []byte{1, 2, 3, 4, 5}, // arbitrary
RelyingPartyID: "goteleport.com",
UserVerification: protocol.VerificationRequired,
@@ -370,7 +370,7 @@ func TestLogin_noCredentials_failsWithoutUserInteraction(t *testing.T) {
}
mfaAssertion := *baseAssertion
mfaAssertion.Response.UserVerification = protocol.VerificationDiscouraged
- mfaAssertion.Response.AllowedCredentials = []protocol.CredentialDescriptor{
+ mfaAssertion.Response.AllowedCredentials = []wantypes.CredentialDescriptor{
{
Type: protocol.PublicKeyCredentialType,
CredentialID: []byte{1, 2, 3, 4, 5}, // arbitrary
@@ -381,7 +381,7 @@ func TestLogin_noCredentials_failsWithoutUserInteraction(t *testing.T) {
for _, test := range []struct {
name string
user string
- assertion *wanlib.CredentialAssertion
+ assertion *wantypes.CredentialAssertion
}{
{
name: "passwordless empty user",
@@ -415,29 +415,29 @@ func TestLogin_noCredentials_failsWithoutUserInteraction(t *testing.T) {
const userLlama = "llama"
const userAlpaca = "alpaca"
rrk := true
- cc1 := &wanlib.CredentialCreation{
- Response: protocol.PublicKeyCredentialCreationOptions{
+ cc1 := &wantypes.CredentialCreation{
+ Response: wantypes.PublicKeyCredentialCreationOptions{
Challenge: []byte{1, 2, 3, 4, 5}, // arbitrary, not important here
- RelyingParty: protocol.RelyingPartyEntity{
- CredentialEntity: protocol.CredentialEntity{
+ RelyingParty: wantypes.RelyingPartyEntity{
+ CredentialEntity: wantypes.CredentialEntity{
Name: "Teleport",
},
ID: baseAssertion.Response.RelyingPartyID,
},
- User: protocol.UserEntity{
- CredentialEntity: protocol.CredentialEntity{
+ User: wantypes.UserEntity{
+ CredentialEntity: wantypes.CredentialEntity{
Name: userLlama,
},
DisplayName: "Llama",
ID: []byte{1, 1, 1, 1, 1},
},
- Parameters: []protocol.CredentialParameter{
+ Parameters: []wantypes.CredentialParameter{
{
Type: protocol.PublicKeyCredentialType,
Algorithm: webauthncose.AlgES256,
},
},
- AuthenticatorSelection: protocol.AuthenticatorSelection{
+ AuthenticatorSelection: wantypes.AuthenticatorSelection{
RequireResidentKey: &rrk,
UserVerification: protocol.VerificationRequired,
},
@@ -445,14 +445,14 @@ func TestLogin_noCredentials_failsWithoutUserInteraction(t *testing.T) {
},
}
cc2 := *cc1
- cc2.Response.User = protocol.UserEntity{
- CredentialEntity: protocol.CredentialEntity{
+ cc2.Response.User = wantypes.UserEntity{
+ CredentialEntity: wantypes.CredentialEntity{
Name: userAlpaca,
},
DisplayName: "Alpaca",
ID: []byte{1, 1, 1, 1, 2},
}
- for _, cc := range []*wanlib.CredentialCreation{cc1, &cc2} {
+ for _, cc := range []*wantypes.CredentialCreation{cc1, &cc2} {
reg, err := touchid.Register(origin, cc)
require.NoError(t, err, "Register failed")
require.NoError(t, reg.Confirm(), "Confirm failed")
@@ -461,7 +461,7 @@ func TestLogin_noCredentials_failsWithoutUserInteraction(t *testing.T) {
mfaAllCreds := mfaAssertion
mfaAllCreds.Response.AllowedCredentials = nil
for _, c := range fake.creds {
- mfaAllCreds.Response.AllowedCredentials = append(mfaAllCreds.Response.AllowedCredentials, protocol.CredentialDescriptor{
+ mfaAllCreds.Response.AllowedCredentials = append(mfaAllCreds.Response.AllowedCredentials, wantypes.CredentialDescriptor{
Type: protocol.PublicKeyCredentialType,
CredentialID: []byte(c.id),
})
@@ -471,7 +471,7 @@ func TestLogin_noCredentials_failsWithoutUserInteraction(t *testing.T) {
for _, test := range []struct {
name string
user string
- assertion *wanlib.CredentialAssertion
+ assertion *wantypes.CredentialAssertion
}{
{
name: "passwordless existing credentials",
@@ -539,17 +539,17 @@ func TestLogin_credentialPicker(t *testing.T) {
const rpID = "goteleport.com"
const origin = "https://goteleport.com"
- baseAssertion := &wanlib.CredentialAssertion{
- Response: protocol.PublicKeyCredentialRequestOptions{
+ baseAssertion := &wantypes.CredentialAssertion{
+ Response: wantypes.PublicKeyCredentialRequestOptions{
Challenge: []byte{1, 2, 3, 4, 5}, // arbitrary
RelyingPartyID: rpID,
UserVerification: protocol.VerificationRequired,
},
}
- newAssertion := func(allowedCreds [][]byte) *wanlib.CredentialAssertion {
+ newAssertion := func(allowedCreds [][]byte) *wantypes.CredentialAssertion {
cp := *baseAssertion
for _, id := range allowedCreds {
- cp.Response.AllowedCredentials = append(cp.Response.AllowedCredentials, protocol.CredentialDescriptor{
+ cp.Response.AllowedCredentials = append(cp.Response.AllowedCredentials, wantypes.CredentialDescriptor{
Type: protocol.PublicKeyCredentialType,
CredentialID: id,
})
diff --git a/lib/auth/touchid/attempt.go b/lib/auth/touchid/attempt.go
index ed1bd1fcc7a11..549752ddf7025 100644
--- a/lib/auth/touchid/attempt.go
+++ b/lib/auth/touchid/attempt.go
@@ -19,7 +19,7 @@ import (
"github.com/gravitational/trace"
- wanlib "github.com/gravitational/teleport/lib/auth/webauthn"
+ wantypes "github.com/gravitational/teleport/lib/auth/webauthntypes"
)
// ErrAttemptFailed is returned by AttemptLogin and AttemptDeleteNonInteractive
@@ -54,7 +54,7 @@ func (e *ErrAttemptFailed) As(target interface{}) bool {
// AttemptLogin attempts a touch ID login.
// It returns ErrAttemptFailed if the attempt failed before user interaction.
// See Login.
-func AttemptLogin(origin, user string, assertion *wanlib.CredentialAssertion, picker CredentialPicker) (*wanlib.CredentialAssertionResponse, string, error) {
+func AttemptLogin(origin, user string, assertion *wantypes.CredentialAssertion, picker CredentialPicker) (*wantypes.CredentialAssertionResponse, string, error) {
resp, actualUser, err := Login(origin, user, assertion, picker)
switch {
case errors.Is(err, ErrNotAvailable), errors.Is(err, ErrCredentialNotFound):
diff --git a/lib/auth/usertoken_test.go b/lib/auth/usertoken_test.go
index 1f0467f4d0f59..ba6379caf7a07 100644
--- a/lib/auth/usertoken_test.go
+++ b/lib/auth/usertoken_test.go
@@ -34,7 +34,7 @@ import (
"github.com/gravitational/teleport/api/constants"
"github.com/gravitational/teleport/api/types"
apievents "github.com/gravitational/teleport/api/types/events"
- "github.com/gravitational/teleport/api/types/webauthn"
+ wanpb "github.com/gravitational/teleport/api/types/webauthn"
"github.com/gravitational/teleport/lib/defaults"
"github.com/gravitational/teleport/lib/events"
"github.com/gravitational/teleport/lib/events/eventstest"
@@ -399,7 +399,7 @@ func TestCreatePrivilegeToken_WithLock(t *testing.T) {
getReq: func() *proto.CreatePrivilegeTokenRequest {
return &proto.CreatePrivilegeTokenRequest{
ExistingMFAResponse: &proto.MFAAuthenticateResponse{Response: &proto.MFAAuthenticateResponse_Webauthn{
- Webauthn: &webauthn.CredentialAssertionResponse{},
+ Webauthn: &wanpb.CredentialAssertionResponse{},
}},
}
},
diff --git a/lib/auth/webauthn/compat.go b/lib/auth/webauthn/compat.go
new file mode 100644
index 0000000000000..8ffbb4b75c2a1
--- /dev/null
+++ b/lib/auth/webauthn/compat.go
@@ -0,0 +1,38 @@
+// Copyright 2023 Gravitational, Inc
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package webauthn
+
+import wantypes "github.com/gravitational/teleport/lib/auth/webauthntypes"
+
+// TODO(codingllama): Delete aliases and vars below once e/ is updated.
+
+type CredentialAssertion = wantypes.CredentialAssertion
+type CredentialAssertionResponse = wantypes.CredentialAssertionResponse
+type CredentialCreation = wantypes.CredentialCreation
+type CredentialCreationResponse = wantypes.CredentialCreationResponse
+
+var (
+ CredentialAssertionFromProto = wantypes.CredentialAssertionFromProto
+ CredentialAssertionToProto = wantypes.CredentialAssertionToProto
+ CredentialAssertionResponseFromProto = wantypes.CredentialAssertionResponseFromProto
+ CredentialAssertionResponseToProto = wantypes.CredentialAssertionResponseToProto
+)
+
+var (
+ CredentialCreationFromProto = wantypes.CredentialCreationFromProto
+ CredentialCreationToProto = wantypes.CredentialCreationToProto
+ CredentialCreationResponseFromProto = wantypes.CredentialCreationResponseFromProto
+ CredentialCreationResponseToProto = wantypes.CredentialCreationResponseToProto
+)
diff --git a/lib/auth/webauthn/extensions.go b/lib/auth/webauthn/extensions.go
deleted file mode 100644
index cc81a53dddc11..0000000000000
--- a/lib/auth/webauthn/extensions.go
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
-Copyright 2021 Gravitational, Inc.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package webauthn
-
-// AppIDExtension is the key for the appid extension.
-// https://www.w3.org/TR/webauthn-2/#sctn-appid-extension.
-const AppIDExtension = "appid"
diff --git a/lib/auth/webauthn/httpserver/README.md b/lib/auth/webauthn/httpserver/README.md
deleted file mode 100644
index bd7dc6a975389..0000000000000
--- a/lib/auth/webauthn/httpserver/README.md
+++ /dev/null
@@ -1,41 +0,0 @@
-# Webauthn httpserver
-
-The httpserver package contains a toy Webauthn HTTPS server used to test web
-integration and the interplay between web-registered and tsh-registered devices.
-
-Devices registered via either interface should be able to be used
-interchangeably (with the exception of Touch ID, which is always tied to a
-specific app).
-
-This is meant for local testing and debugging only. Keep it far away from any
-production uses.
-
-## Why this exists?
-
-* It is a simple way to test web integration
-* It is a simple way to interact with Touch ID
-* Device registration (currently) relies on a streaming RPC, which is difficult
- to interact with using pure Js
-
-Note that browser Webauthn APIs need a secure context (or you have to disable a
-bunch of checks in your browser, YMMV).
-
-## Usage
-
-1. Start the Teleport service
-2. Start the httpserver
-
-```shell
-# Generate TLS certificates for the server
-# (Eg, `cd; mkcert localhost 127.0.0.1 ::1`)
-
-# Start the test server
-# cd /path/to/teleport/repo
-go run ./lib/auth/webauthn/httpserver/ \
- -cert_file ~/localhost+2.pem \
- -key_file ~/localhost+3-key.pem
-```
-
-3. Navigate to https://localhost:8080/index.html
-4. ?
-5. Profit
diff --git a/lib/auth/webauthn/httpserver/index.html b/lib/auth/webauthn/httpserver/index.html
deleted file mode 100644
index a31d818cbad60..0000000000000
--- a/lib/auth/webauthn/httpserver/index.html
+++ /dev/null
@@ -1,199 +0,0 @@
-
-
-
-
-
- WebAuthn Playground
-
-
-
-
-
-
-
-
-
-
-
diff --git a/lib/auth/webauthn/httpserver/main.go b/lib/auth/webauthn/httpserver/main.go
deleted file mode 100644
index 4a009d704a40c..0000000000000
--- a/lib/auth/webauthn/httpserver/main.go
+++ /dev/null
@@ -1,319 +0,0 @@
-// Copyright 2021 Gravitational, Inc
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package main
-
-import (
- "bytes"
- "context"
- _ "embed" // enable embed
- "encoding/json"
- "flag"
- "fmt"
- "io"
- "log"
- "net/http"
- "sync"
-
- "github.com/gravitational/trace"
-
- apiclient "github.com/gravitational/teleport/api/client"
- "github.com/gravitational/teleport/api/client/proto"
- wanlib "github.com/gravitational/teleport/lib/auth/webauthn"
- libclient "github.com/gravitational/teleport/lib/client"
-)
-
-//go:embed index.html
-var indexPage []byte
-
-var (
- addr = flag.String("addr", "localhost:8080", "Server bind address")
- certFile = flag.String("cert_file", "cert.pem", "Cert PEM file")
- keyFile = flag.String("key_file", "cert-key.pem", "Key PEM file")
-
- authAddr = flag.String("auth_addr", "localhost:3025", "Teleport Auth address")
- webAddr = flag.String("web_addr", "localhost:3080", "Teleport Web API address")
-)
-
-func main() {
- flag.Parse()
- if err := run(); err != nil {
- log.Fatal(err)
- }
-}
-
-func run() error {
- ctx, cancel := context.WithCancel(context.Background())
- defer cancel()
-
- fmt.Println("Starting Teleport client")
- profile := apiclient.LoadProfile("", "")
- teleport, err := apiclient.New(ctx, apiclient.Config{
- Addrs: []string{*authAddr},
- Credentials: []apiclient.Credentials{profile},
- })
- if err != nil {
- fmt.Println("Teleport client startup failed, did you run tsh login?")
- return trace.Wrap(err)
- }
-
- http.Handle("/", http.RedirectHandler("/index.html", http.StatusSeeOther))
- http.HandleFunc("/index.html", func(w http.ResponseWriter, r *http.Request) {
- w.Header().Set("Content-Type", "text/html; charset=UTF-8")
- w.WriteHeader(http.StatusOK)
- w.Write(indexPage)
- })
-
- s := &server{
- ctx: ctx,
- teleport: teleport,
- }
- http.HandleFunc("/login/1", s.login1)
- http.HandleFunc("/login/2", s.login2)
- http.HandleFunc("/register/1", s.register1)
- http.HandleFunc("/register/2", s.register2)
-
- fmt.Printf("Listening at %v\n", *addr)
- return http.ListenAndServeTLS(*addr, *certFile, *keyFile, nil /* handler */)
-}
-
-type server struct {
- ctx context.Context
- teleport *apiclient.Client
-
- mu sync.Mutex
- inFlightAddStream *proto.AuthService_AddMFADeviceClient
-}
-
-type login1Request struct {
- User string `json:"user"`
- Pass string `json:"pass"`
-}
-
-func (s *server) login1(w http.ResponseWriter, r *http.Request) {
- var req login1Request
- if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
- http.Error(w, err.Error(), http.StatusBadRequest)
- return
- }
-
- // Get login challenge.
- body, err := json.Marshal(&libclient.MFAChallengeRequest{
- User: req.User,
- Pass: req.Pass,
- })
- if err != nil {
- http.Error(w, err.Error(), http.StatusInternalServerError)
- return
- }
- resp, err := http.Post("https://"+*webAddr+"/webapi/mfa/login/begin", "application/json", bytes.NewReader(body))
- if err != nil {
- http.Error(w, err.Error(), http.StatusBadRequest)
- return
- }
- defer resp.Body.Close()
- if resp.StatusCode != http.StatusOK {
- log.Printf("INFO /mfa/login/begin: %#v", resp)
- http.Error(w, "Unexpected status from /mfa/login/begin", http.StatusBadRequest)
- }
- var challenge libclient.MFAAuthenticateChallenge
- if err := json.NewDecoder(resp.Body).Decode(&challenge); err != nil {
- http.Error(w, err.Error(), http.StatusBadRequest)
- return
- }
- if challenge.WebauthnChallenge == nil {
- http.Error(w, "nil credential assertion", http.StatusBadRequest)
- return
- }
-
- w.Header().Set("Content-Type", "application/json")
- w.WriteHeader(http.StatusOK)
- if err := json.NewEncoder(w).Encode(challenge.WebauthnChallenge); err != nil {
- log.Println(err)
- }
-}
-
-type login2Request struct {
- wanlib.CredentialAssertionResponse
- User string `json:"user"`
-}
-
-func (s *server) login2(w http.ResponseWriter, r *http.Request) {
- // Request body is a wanlib.CredentialAssertionResponse.
- // User passed as a query param to make things simpler.
-
- var req login2Request
- if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
- http.Error(w, err.Error(), http.StatusBadRequest)
- return
- }
-
- body, err := json.Marshal(&libclient.AuthenticateWebUserRequest{
- User: req.User,
- WebauthnAssertionResponse: &req.CredentialAssertionResponse,
- })
- if err != nil {
- http.Error(w, err.Error(), http.StatusInternalServerError)
- return
- }
-
- // Solve login challenge
- resp, err := http.Post("https://"+*webAddr+"/webapi/mfa/login/finishsession", "application/json", bytes.NewReader(body))
- if err != nil {
- http.Error(w, err.Error(), http.StatusInternalServerError)
- return
- }
- io.Copy(io.Discard, resp.Body)
- resp.Body.Close()
- if resp.StatusCode != http.StatusOK {
- log.Printf("INFO /mfa/login/finishsession: %#v", resp)
- http.Error(w, "Unexpected status from /mfa/login/finishsession", http.StatusBadRequest)
- }
-
- // Login OK.
- w.WriteHeader(http.StatusOK)
-}
-
-type register1Request struct {
- User string `json:"user"`
- Pass string `json:"pass"`
- DevName string `json:"dev_name"`
- TOTPCode string `json:"totp_code"`
-}
-
-func (s *server) register1(w http.ResponseWriter, r *http.Request) {
- s.mu.Lock() // Hold lock for the entire time, we don't care.
- defer s.mu.Unlock()
-
- var req register1Request
- if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
- http.Error(w, err.Error(), http.StatusBadRequest)
- return
- }
-
- // Init stream with device name and type.
- ctx := s.ctx
- stream, err := s.teleport.AddMFADevice(ctx)
- if err != nil {
- http.Error(w, err.Error(), http.StatusBadRequest)
- return
- }
- if err := stream.Send(&proto.AddMFADeviceRequest{
- Request: &proto.AddMFADeviceRequest_Init{
- Init: &proto.AddMFADeviceRequestInit{
- DeviceName: req.DevName,
- DeviceType: proto.DeviceType_DEVICE_TYPE_WEBAUTHN,
- },
- },
- }); err != nil {
- http.Error(w, err.Error(), http.StatusBadRequest)
- return
- }
-
- // Solve authn challenge.
- resp, err := stream.Recv()
- if err != nil {
- http.Error(w, err.Error(), http.StatusBadRequest)
- return
- }
- var authResp *proto.MFAAuthenticateResponse
- challenge := resp.GetExistingMFAChallenge()
- switch {
- case challenge.GetTOTP() == nil && challenge.GetWebauthnChallenge() == nil: // aka empty challenge
- authResp = &proto.MFAAuthenticateResponse{}
- case challenge.GetTOTP() != nil:
- authResp = &proto.MFAAuthenticateResponse{
- Response: &proto.MFAAuthenticateResponse_TOTP{
- TOTP: &proto.TOTPResponse{
- Code: req.TOTPCode,
- },
- },
- }
- default:
- http.Error(w, "TOTP challenge not present", http.StatusBadRequest)
- return
- }
- if err := stream.Send(&proto.AddMFADeviceRequest{
- Request: &proto.AddMFADeviceRequest_ExistingMFAResponse{
- ExistingMFAResponse: authResp,
- },
- }); err != nil {
- http.Error(w, err.Error(), http.StatusBadRequest)
- return
- }
-
- resp, err = stream.Recv()
- if err != nil {
- http.Error(w, err.Error(), http.StatusBadRequest)
- return
- }
- ccProto := resp.GetNewMFARegisterChallenge().GetWebauthn()
- if ccProto == nil {
- http.Error(w, "nil credential creation", http.StatusBadRequest)
- return
- }
-
- cc := wanlib.CredentialCreationFromProto(ccProto)
- w.Header().Set("Content-Type", "application/json")
- w.WriteHeader(http.StatusOK)
- if err := json.NewEncoder(w).Encode(cc); err != nil {
- log.Println(err)
- }
-
- s.inFlightAddStream = &stream // Save stream for 2nd step
-}
-
-func (s *server) register2(w http.ResponseWriter, r *http.Request) {
- // Request body is a wanlib.CredentialCreationResponse.
-
- s.mu.Lock() // Hold lock for the entire time, we don't care.
- defer s.mu.Unlock()
-
- if s.inFlightAddStream == nil {
- http.Error(w, "In-flight add stream is nil", http.StatusBadRequest)
- return
- }
- stream := *s.inFlightAddStream
-
- var ccr wanlib.CredentialCreationResponse
- if err := json.NewDecoder(r.Body).Decode(&ccr); err != nil {
- http.Error(w, err.Error(), http.StatusBadRequest)
- return
- }
-
- // Send register response.
- if err := stream.Send(&proto.AddMFADeviceRequest{
- Request: &proto.AddMFADeviceRequest_NewMFARegisterResponse{
- NewMFARegisterResponse: &proto.MFARegisterResponse{
- Response: &proto.MFARegisterResponse_Webauthn{
- Webauthn: wanlib.CredentialCreationResponseToProto(&ccr),
- },
- },
- },
- }); err != nil {
- http.Error(w, err.Error(), http.StatusBadRequest)
- return
- }
- resp, err := stream.Recv()
- if err != nil {
- http.Error(w, err.Error(), http.StatusBadRequest)
- return
- }
- if resp.GetAck() == nil {
- log.Printf("WARN Expected Ack, got %#v", resp)
- }
-
- s.inFlightAddStream = nil
- w.WriteHeader(http.StatusOK)
-}
diff --git a/lib/auth/webauthn/login.go b/lib/auth/webauthn/login.go
index e18a1d6f4065f..b550529351a36 100644
--- a/lib/auth/webauthn/login.go
+++ b/lib/auth/webauthn/login.go
@@ -31,7 +31,8 @@ import (
"golang.org/x/exp/slices"
"github.com/gravitational/teleport/api/types"
- wantypes "github.com/gravitational/teleport/api/types/webauthn"
+ wanpb "github.com/gravitational/teleport/api/types/webauthn"
+ wantypes "github.com/gravitational/teleport/lib/auth/webauthntypes"
)
// loginIdentity contains the subset of services.Identity methods used by
@@ -50,8 +51,8 @@ type loginIdentity interface {
// * Passwordless uses global variants
// (services.Identity.Update/Get/DeleteGlobalWebauthnSessionData methods).
type sessionIdentity interface {
- Upsert(ctx context.Context, user string, sd *wantypes.SessionData) error
- Get(ctx context.Context, user string, challenge string) (*wantypes.SessionData, error)
+ Upsert(ctx context.Context, user string, sd *wanpb.SessionData) error
+ Get(ctx context.Context, user string, challenge string) (*wanpb.SessionData, error)
Delete(ctx context.Context, user string, challenge string) error
}
@@ -64,7 +65,7 @@ type loginFlow struct {
sessionData sessionIdentity
}
-func (f *loginFlow) begin(ctx context.Context, user string, passwordless bool) (*CredentialAssertion, error) {
+func (f *loginFlow) begin(ctx context.Context, user string, passwordless bool) (*wantypes.CredentialAssertion, error) {
if user == "" && !passwordless {
return nil, trace.BadParameter("user required")
}
@@ -134,7 +135,7 @@ func (f *loginFlow) begin(ctx context.Context, user string, passwordless bool) (
if f.U2F != nil && f.U2F.AppID != "" {
// See https://www.w3.org/TR/webauthn-2/#sctn-appid-extension.
opts = append(opts, wan.WithAssertionExtensions(protocol.AuthenticationExtensions{
- AppIDExtension: f.U2F.AppID,
+ wantypes.AppIDExtension: f.U2F.AppID,
}))
}
@@ -168,7 +169,7 @@ func (f *loginFlow) begin(ctx context.Context, user string, passwordless bool) (
return nil, trace.Wrap(err)
}
- return (*CredentialAssertion)(assertion), nil
+ return wantypes.CredentialAssertionFromProtocol(assertion), nil
}
func (f *loginFlow) getWebID(ctx context.Context, user string) ([]byte, error) {
@@ -182,7 +183,7 @@ func (f *loginFlow) getWebID(ctx context.Context, user string) ([]byte, error) {
return wla.UserID, nil
}
-func (f *loginFlow) finish(ctx context.Context, user string, resp *CredentialAssertionResponse, passwordless bool) (*types.MFADevice, string, error) {
+func (f *loginFlow) finish(ctx context.Context, user string, resp *wantypes.CredentialAssertionResponse, passwordless bool) (*types.MFADevice, string, error) {
switch {
case user == "" && !passwordless:
return nil, "", trace.BadParameter("user required")
@@ -318,7 +319,7 @@ func (f *loginFlow) finish(ctx context.Context, user string, resp *CredentialAss
return dev, user, nil
}
-func parseCredentialResponse(resp *CredentialAssertionResponse) (*protocol.ParsedCredentialAssertionData, error) {
+func parseCredentialResponse(resp *wantypes.CredentialAssertionResponse) (*protocol.ParsedCredentialAssertionData, error) {
// Do not pass extensions on to duo-labs/webauthn, they won't go past JSON
// unmarshal.
exts := resp.Extensions
diff --git a/lib/auth/webauthn/login_mfa.go b/lib/auth/webauthn/login_mfa.go
index 33f6cc4c60a41..6f595759dcbf3 100644
--- a/lib/auth/webauthn/login_mfa.go
+++ b/lib/auth/webauthn/login_mfa.go
@@ -21,7 +21,8 @@ import (
"github.com/gravitational/trace"
"github.com/gravitational/teleport/api/types"
- wantypes "github.com/gravitational/teleport/api/types/webauthn"
+ wanpb "github.com/gravitational/teleport/api/types/webauthn"
+ wantypes "github.com/gravitational/teleport/lib/auth/webauthntypes"
)
// ErrInvalidCredentials is a special kind of credential "NotFound" error, where
@@ -39,8 +40,8 @@ type LoginIdentity interface {
GetMFADevices(ctx context.Context, user string, withSecrets bool) ([]*types.MFADevice, error)
UpsertMFADevice(ctx context.Context, user string, d *types.MFADevice) error
- UpsertWebauthnSessionData(ctx context.Context, user, sessionID string, sd *wantypes.SessionData) error
- GetWebauthnSessionData(ctx context.Context, user, sessionID string) (*wantypes.SessionData, error)
+ UpsertWebauthnSessionData(ctx context.Context, user, sessionID string, sd *wanpb.SessionData) error
+ GetWebauthnSessionData(ctx context.Context, user, sessionID string) (*wanpb.SessionData, error)
DeleteWebauthnSessionData(ctx context.Context, user, sessionID string) error
}
@@ -89,7 +90,7 @@ type LoginFlow struct {
// assertion.
// As a side effect Begin may assign (and record in storage) a WebAuthn ID for
// the user.
-func (f *LoginFlow) Begin(ctx context.Context, user string) (*CredentialAssertion, error) {
+func (f *LoginFlow) Begin(ctx context.Context, user string) (*wantypes.CredentialAssertion, error) {
lf := &loginFlow{
U2F: f.U2F,
Webauthn: f.Webauthn,
@@ -103,7 +104,7 @@ func (f *LoginFlow) Begin(ctx context.Context, user string) (*CredentialAssertio
// It returns the MFADevice used to solve the challenge. If login is successful,
// Finish has the side effect of updating the counter and last used timestamp of
// the returned device.
-func (f *LoginFlow) Finish(ctx context.Context, user string, resp *CredentialAssertionResponse) (*types.MFADevice, error) {
+func (f *LoginFlow) Finish(ctx context.Context, user string, resp *wantypes.CredentialAssertionResponse) (*types.MFADevice, error) {
lf := &loginFlow{
U2F: f.U2F,
Webauthn: f.Webauthn,
@@ -125,11 +126,11 @@ func (m mfaIdentity) GetTeleportUserByWebauthnID(_ context.Context, _ []byte) (s
// userSessionStorage implements sessionIdentity using LoginFlow.
type userSessionStorage LoginFlow
-func (s *userSessionStorage) Upsert(ctx context.Context, user string, sd *wantypes.SessionData) error {
+func (s *userSessionStorage) Upsert(ctx context.Context, user string, sd *wanpb.SessionData) error {
return s.Identity.UpsertWebauthnSessionData(ctx, user, scopeLogin, sd)
}
-func (s *userSessionStorage) Get(ctx context.Context, user string, _ string) (*wantypes.SessionData, error) {
+func (s *userSessionStorage) Get(ctx context.Context, user string, _ string) (*wanpb.SessionData, error) {
return s.Identity.GetWebauthnSessionData(ctx, user, scopeLogin)
}
diff --git a/lib/auth/webauthn/login_passwordless.go b/lib/auth/webauthn/login_passwordless.go
index 71584305ecf25..a659d6fc7e8aa 100644
--- a/lib/auth/webauthn/login_passwordless.go
+++ b/lib/auth/webauthn/login_passwordless.go
@@ -20,7 +20,8 @@ import (
"errors"
"github.com/gravitational/teleport/api/types"
- wantypes "github.com/gravitational/teleport/api/types/webauthn"
+ wanpb "github.com/gravitational/teleport/api/types/webauthn"
+ wantypes "github.com/gravitational/teleport/lib/auth/webauthntypes"
)
// PasswordlessIdentity represents the subset of Identity methods used by
@@ -29,8 +30,8 @@ type PasswordlessIdentity interface {
GetMFADevices(ctx context.Context, user string, withSecrets bool) ([]*types.MFADevice, error)
UpsertMFADevice(ctx context.Context, user string, d *types.MFADevice) error
- UpsertGlobalWebauthnSessionData(ctx context.Context, scope, id string, sd *wantypes.SessionData) error
- GetGlobalWebauthnSessionData(ctx context.Context, scope, id string) (*wantypes.SessionData, error)
+ UpsertGlobalWebauthnSessionData(ctx context.Context, scope, id string, sd *wanpb.SessionData) error
+ GetGlobalWebauthnSessionData(ctx context.Context, scope, id string) (*wanpb.SessionData, error)
DeleteGlobalWebauthnSessionData(ctx context.Context, scope, id string) error
GetTeleportUserByWebauthnID(ctx context.Context, webID []byte) (string, error)
}
@@ -44,7 +45,7 @@ type PasswordlessFlow struct {
// Begin is the first step of the passwordless login flow.
// It works similarly to LoginFlow.Begin, but it doesn't require a Teleport
// username nor implies a previous password-validation step.
-func (f *PasswordlessFlow) Begin(ctx context.Context) (*CredentialAssertion, error) {
+func (f *PasswordlessFlow) Begin(ctx context.Context) (*wantypes.CredentialAssertion, error) {
lf := &loginFlow{
Webauthn: f.Webauthn,
identity: passwordlessIdentity{f.Identity},
@@ -56,7 +57,7 @@ func (f *PasswordlessFlow) Begin(ctx context.Context) (*CredentialAssertion, err
// Finish is the last step of the passwordless login flow.
// It works similarly to LoginFlow.Finish, but the user identity is established
// via the response UserHandle, instead of an explicit Teleport username.
-func (f *PasswordlessFlow) Finish(ctx context.Context, resp *CredentialAssertionResponse) (*types.MFADevice, string, error) {
+func (f *PasswordlessFlow) Finish(ctx context.Context, resp *wantypes.CredentialAssertionResponse) (*types.MFADevice, string, error) {
lf := &loginFlow{
Webauthn: f.Webauthn,
identity: passwordlessIdentity{f.Identity},
@@ -79,12 +80,12 @@ func (p passwordlessIdentity) GetWebauthnLocalAuth(ctx context.Context, user str
type globalSessionStorage PasswordlessFlow
-func (g *globalSessionStorage) Upsert(ctx context.Context, user string, sd *wantypes.SessionData) error {
+func (g *globalSessionStorage) Upsert(ctx context.Context, user string, sd *wanpb.SessionData) error {
id := base64.RawURLEncoding.EncodeToString(sd.Challenge)
return g.Identity.UpsertGlobalWebauthnSessionData(ctx, scopeLogin, id, sd)
}
-func (g *globalSessionStorage) Get(ctx context.Context, user string, challenge string) (*wantypes.SessionData, error) {
+func (g *globalSessionStorage) Get(ctx context.Context, user string, challenge string) (*wanpb.SessionData, error) {
return g.Identity.GetGlobalWebauthnSessionData(ctx, scopeLogin, challenge)
}
diff --git a/lib/auth/webauthn/login_test.go b/lib/auth/webauthn/login_test.go
index bc42edb2d97b1..27306b6e14f63 100644
--- a/lib/auth/webauthn/login_test.go
+++ b/lib/auth/webauthn/login_test.go
@@ -31,9 +31,10 @@ import (
"github.com/stretchr/testify/require"
"github.com/gravitational/teleport/api/types"
- wantypes "github.com/gravitational/teleport/api/types/webauthn"
+ wanpb "github.com/gravitational/teleport/api/types/webauthn"
"github.com/gravitational/teleport/lib/auth/mocku2f"
wanlib "github.com/gravitational/teleport/lib/auth/webauthn"
+ wantypes "github.com/gravitational/teleport/lib/auth/webauthntypes"
)
func TestLoginFlow_BeginFinish(t *testing.T) {
@@ -127,7 +128,7 @@ func TestLoginFlow_BeginFinish(t *testing.T) {
// Did we record the SessionData in storage?
require.Len(t, identity.SessionData, 1)
// Did we record the web ID in the SessionData?
- var sd *wantypes.SessionData
+ var sd *wanpb.SessionData
for _, v := range identity.SessionData {
sd = v // Retrieve without guessing the key
break
@@ -265,27 +266,27 @@ func TestLoginFlow_Finish_errors(t *testing.T) {
tests := []struct {
name string
user string
- createResp func() *wanlib.CredentialAssertionResponse
+ createResp func() *wantypes.CredentialAssertionResponse
}{
{
name: "NOK empty user",
user: "",
- createResp: func() *wanlib.CredentialAssertionResponse { return okResp },
+ createResp: func() *wantypes.CredentialAssertionResponse { return okResp },
},
{
name: "NOK nil resp",
user: user,
- createResp: func() *wanlib.CredentialAssertionResponse { return nil },
+ createResp: func() *wantypes.CredentialAssertionResponse { return nil },
},
{
name: "NOK empty resp",
user: user,
- createResp: func() *wanlib.CredentialAssertionResponse { return &wanlib.CredentialAssertionResponse{} },
+ createResp: func() *wantypes.CredentialAssertionResponse { return &wantypes.CredentialAssertionResponse{} },
},
{
name: "NOK assertion with bad origin",
user: user,
- createResp: func() *wanlib.CredentialAssertionResponse {
+ createResp: func() *wantypes.CredentialAssertionResponse {
assertion, err := webLogin.Begin(ctx, user)
require.NoError(t, err)
resp, err := key.SignAssertion("https://badorigin.com", assertion)
@@ -296,7 +297,7 @@ func TestLoginFlow_Finish_errors(t *testing.T) {
{
name: "NOK assertion with bad RPID",
user: user,
- createResp: func() *wanlib.CredentialAssertionResponse {
+ createResp: func() *wantypes.CredentialAssertionResponse {
assertion, err := webLogin.Begin(ctx, user)
require.NoError(t, err)
assertion.Response.RelyingPartyID = "badrpid.com"
@@ -309,7 +310,7 @@ func TestLoginFlow_Finish_errors(t *testing.T) {
{
name: "NOK assertion signed by unknown device",
user: user,
- createResp: func() *wanlib.CredentialAssertionResponse {
+ createResp: func() *wantypes.CredentialAssertionResponse {
assertion, err := webLogin.Begin(ctx, user)
require.NoError(t, err)
@@ -326,7 +327,7 @@ func TestLoginFlow_Finish_errors(t *testing.T) {
{
name: "NOK assertion with invalid signature",
user: user,
- createResp: func() *wanlib.CredentialAssertionResponse {
+ createResp: func() *wantypes.CredentialAssertionResponse {
assertion, err := webLogin.Begin(ctx, user)
require.NoError(t, err)
// Flip a challenge bit, this should be enough to consistently fail
@@ -409,12 +410,12 @@ func TestPasswordlessFlow_BeginAndFinish(t *testing.T) {
// Verify that we recorded user verification requirements in storage.
require.Len(t, identity.SessionData, 1)
- var sd *wantypes.SessionData
+ var sd *wanpb.SessionData
for _, v := range identity.SessionData {
sd = v // Get SessionData without guessing the key.
break
}
- wantSD := &wantypes.SessionData{
+ wantSD := &wanpb.SessionData{
Challenge: sd.Challenge,
UserId: nil, // aka unset
AllowCredentials: nil, // aka unset
@@ -471,13 +472,13 @@ func TestPasswordlessFlow_Finish_errors(t *testing.T) {
tests := []struct {
name string
- createResp func() *wanlib.CredentialAssertionResponse
+ createResp func() *wantypes.CredentialAssertionResponse
assertErrType func(error) bool
wantErrMsg string
}{
{
name: "NOK response without UserID",
- createResp: func() *wanlib.CredentialAssertionResponse {
+ createResp: func() *wantypes.CredentialAssertionResponse {
// UserHandle is already nil on assertionResp
return assertionResp
},
@@ -486,7 +487,7 @@ func TestPasswordlessFlow_Finish_errors(t *testing.T) {
},
{
name: "NOK unknown user handle",
- createResp: func() *wanlib.CredentialAssertionResponse {
+ createResp: func() *wantypes.CredentialAssertionResponse {
unknownHandle := make([]byte, 10 /* arbitrary */)
cp := *assertionResp
cp.AssertionResponse.UserHandle = unknownHandle
@@ -627,7 +628,7 @@ type fakeIdentity struct {
// It's automatically assigned when UpsertWebauthnLocalAuth is called.
MappedUser string
UpdatedDevices []*types.MFADevice
- SessionData map[string]*wantypes.SessionData
+ SessionData map[string]*wanpb.SessionData
}
func newFakeIdentity(user string, devices ...*types.MFADevice) *fakeIdentity {
@@ -642,7 +643,7 @@ func newFakeIdentity(user string, devices ...*types.MFADevice) *fakeIdentity {
},
},
},
- SessionData: make(map[string]*wantypes.SessionData),
+ SessionData: make(map[string]*wanpb.SessionData),
}
}
@@ -687,12 +688,12 @@ func (f *fakeIdentity) GetTeleportUserByWebauthnID(ctx context.Context, webID []
return f.MappedUser, nil
}
-func (f *fakeIdentity) UpsertWebauthnSessionData(ctx context.Context, user, sessionID string, sd *wantypes.SessionData) error {
+func (f *fakeIdentity) UpsertWebauthnSessionData(ctx context.Context, user, sessionID string, sd *wanpb.SessionData) error {
f.SessionData[sessionDataKey(user, sessionID)] = sd
return nil
}
-func (f *fakeIdentity) GetWebauthnSessionData(ctx context.Context, user, sessionID string) (*wantypes.SessionData, error) {
+func (f *fakeIdentity) GetWebauthnSessionData(ctx context.Context, user, sessionID string) (*wanpb.SessionData, error) {
sd, ok := f.SessionData[sessionDataKey(user, sessionID)]
if !ok {
return nil, trace.NotFound("not found")
@@ -709,12 +710,12 @@ func sessionDataKey(user string, sessionID string) string {
return fmt.Sprintf("user/%v/%v", user, sessionID)
}
-func (f *fakeIdentity) UpsertGlobalWebauthnSessionData(ctx context.Context, scope, id string, sd *wantypes.SessionData) error {
+func (f *fakeIdentity) UpsertGlobalWebauthnSessionData(ctx context.Context, scope, id string, sd *wanpb.SessionData) error {
f.SessionData[globalSessionDataKey(scope, id)] = sd
return nil
}
-func (f *fakeIdentity) GetGlobalWebauthnSessionData(ctx context.Context, scope, id string) (*wantypes.SessionData, error) {
+func (f *fakeIdentity) GetGlobalWebauthnSessionData(ctx context.Context, scope, id string) (*wanpb.SessionData, error) {
sd, ok := f.SessionData[globalSessionDataKey(scope, id)]
if !ok {
return nil, trace.NotFound("not found")
diff --git a/lib/auth/webauthn/messages.go b/lib/auth/webauthn/messages.go
deleted file mode 100644
index 94218687e2a9d..0000000000000
--- a/lib/auth/webauthn/messages.go
+++ /dev/null
@@ -1,143 +0,0 @@
-// Copyright 2021 Gravitational, Inc
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package webauthn
-
-import (
- "github.com/go-webauthn/webauthn/protocol"
- "github.com/gravitational/trace"
-)
-
-// CredentialAssertion is the payload sent to authenticators to initiate login.
-type CredentialAssertion protocol.CredentialAssertion
-
-// Validate performs client-side validation of CredentialAssertion.
-// It makes sure that data are valid and can be sent to authenticator.
-// This is general purpose validation and authenticator should add its own
-// on top of it, if necessary.
-func (ca *CredentialAssertion) Validate() error {
- switch {
- case ca == nil:
- return trace.BadParameter("credential assertion required")
- case len(ca.Response.Challenge) == 0:
- return trace.BadParameter("credential assertion challenge required")
- case ca.Response.RelyingPartyID == "":
- return trace.BadParameter("credential assertion relying party ID required")
- }
- return nil
-}
-
-// CredentialAssertionResponse is the reply from authenticators to complete
-// login.
-type CredentialAssertionResponse struct {
- // CredentialAssertionResponse is redefined because, unlike
- // CredentialAssertion, it is likely to be manually created by package users.
- // Redefining allows us to 1) make sure it can be properly JSON-marshaled
- // (protocol.CredentialAssertionResponse.Extensions can't) and 2) we avoid
- // leaking the duo-labs/webauthn dependency.
- // The nesting of types is identical to protocol.CredentialAssertionResponse.
-
- PublicKeyCredential
- AssertionResponse AuthenticatorAssertionResponse `json:"response"`
-}
-
-// CredentialCreation is the payload sent to authenticators to initiate
-// registration.
-type CredentialCreation protocol.CredentialCreation
-
-// RequireResidentKey returns information whether resident key is required or
-// not. It checks ResidentKey and fallbacks to RequireResidentKey.
-func (cc *CredentialCreation) RequireResidentKey() (bool, error) {
- as := cc.Response.AuthenticatorSelection
- switch as.ResidentKey {
- case protocol.ResidentKeyRequirementRequired:
- if as.RequireResidentKey != nil && !*as.RequireResidentKey {
- return false, trace.BadParameter("invalid combination of ResidentKey: %v and RequireResidentKey: %v", as.ResidentKey, *as.RequireResidentKey)
- }
- return true, nil
- case protocol.ResidentKeyRequirementDiscouraged:
- if as.RequireResidentKey != nil && *as.RequireResidentKey {
- return false, trace.BadParameter("invalid combination of ResidentKey: %v and RequireResidentKey: %v", as.ResidentKey, *as.RequireResidentKey)
- }
- return false, nil
- case protocol.ResidentKeyRequirementPreferred:
- return false, nil
- }
- // If ResidentKey is not set, then fallback to the legacy RequireResidentKey
- // field.
- return as.RequireResidentKey != nil && *as.RequireResidentKey, nil
-}
-
-// Validate performs client-side validation of CredentialCreation.
-// It makes sure that data are valid and can be sent to authenticator.
-// This is general purpose validation and authenticator should add its own
-// on top of it, if necessary.
-func (cc *CredentialCreation) Validate() error {
- switch {
- case cc == nil:
- return trace.BadParameter("credential creation required")
- case len(cc.Response.Challenge) == 0:
- return trace.BadParameter("credential creation challenge required")
- case cc.Response.RelyingParty.ID == "":
- return trace.BadParameter("credential creation relying party ID required")
- case len(cc.Response.RelyingParty.Name) == 0:
- return trace.BadParameter("relying party name required")
- case len(cc.Response.User.Name) == 0:
- return trace.BadParameter("user name required")
- case len(cc.Response.User.DisplayName) == 0:
- return trace.BadParameter("user display name required")
- case len(cc.Response.User.ID) == 0:
- return trace.BadParameter("user ID required")
- default:
- return nil
- }
-}
-
-// CredentialCreationResponse is the reply from authenticators to complete
-// registration.
-type CredentialCreationResponse struct {
- // CredentialCreationResponse is manually redefined, instead of directly based
- // in protocol.CredentialCreationResponse, for the same reasoning that
- // CredentialAssertionResponse is - in short, we want a clean package.
- // The nesting of types is identical to protocol.CredentialCreationResponse.
-
- PublicKeyCredential
- AttestationResponse AuthenticatorAttestationResponse `json:"response"`
-}
-
-type PublicKeyCredential struct {
- Credential
- RawID protocol.URLEncodedBase64 `json:"rawId"`
- Extensions *AuthenticationExtensionsClientOutputs `json:"extensions,omitempty"`
-}
-
-type Credential protocol.Credential
-
-type AuthenticationExtensionsClientOutputs struct {
- AppID bool `json:"appid,omitempty"`
-}
-
-type AuthenticatorAssertionResponse struct {
- AuthenticatorResponse
- AuthenticatorData protocol.URLEncodedBase64 `json:"authenticatorData"`
- Signature protocol.URLEncodedBase64 `json:"signature"`
- UserHandle protocol.URLEncodedBase64 `json:"userHandle,omitempty"`
-}
-
-type AuthenticatorResponse protocol.AuthenticatorResponse
-
-type AuthenticatorAttestationResponse struct {
- AuthenticatorResponse
- AttestationObject protocol.URLEncodedBase64 `json:"attestationObject"`
-}
diff --git a/lib/auth/webauthn/register.go b/lib/auth/webauthn/register.go
index fef63d9c5c304..2f16c26569221 100644
--- a/lib/auth/webauthn/register.go
+++ b/lib/auth/webauthn/register.go
@@ -30,7 +30,8 @@ import (
log "github.com/sirupsen/logrus"
"github.com/gravitational/teleport/api/types"
- wantypes "github.com/gravitational/teleport/api/types/webauthn"
+ wanpb "github.com/gravitational/teleport/api/types/webauthn"
+ wantypes "github.com/gravitational/teleport/lib/auth/webauthntypes"
)
// RegistrationIdentity represents the subset of Identity methods used by
@@ -42,8 +43,8 @@ type RegistrationIdentity interface {
GetMFADevices(ctx context.Context, user string, withSecrets bool) ([]*types.MFADevice, error)
UpsertMFADevice(ctx context.Context, user string, d *types.MFADevice) error
- UpsertWebauthnSessionData(ctx context.Context, user, sessionID string, sd *wantypes.SessionData) error
- GetWebauthnSessionData(ctx context.Context, user, sessionID string) (*wantypes.SessionData, error)
+ UpsertWebauthnSessionData(ctx context.Context, user, sessionID string, sd *wanpb.SessionData) error
+ GetWebauthnSessionData(ctx context.Context, user, sessionID string) (*wanpb.SessionData, error)
DeleteWebauthnSessionData(ctx context.Context, user, sessionID string) error
}
@@ -52,7 +53,7 @@ type RegistrationIdentity interface {
func WithInMemorySessionData(identity RegistrationIdentity) RegistrationIdentity {
return &inMemoryIdentity{
RegistrationIdentity: identity,
- sessionData: make(map[string]*wantypes.SessionData),
+ sessionData: make(map[string]*wanpb.SessionData),
}
}
@@ -63,17 +64,17 @@ type inMemoryIdentity struct {
// We don't foresee concurrent use for inMemoryIdentity, but it's easy enough
// to play it safe.
mu sync.RWMutex
- sessionData map[string]*wantypes.SessionData
+ sessionData map[string]*wanpb.SessionData
}
-func (identity *inMemoryIdentity) UpsertWebauthnSessionData(ctx context.Context, user, sessionID string, sd *wantypes.SessionData) error {
+func (identity *inMemoryIdentity) UpsertWebauthnSessionData(ctx context.Context, user, sessionID string, sd *wanpb.SessionData) error {
identity.mu.Lock()
defer identity.mu.Unlock()
identity.sessionData[sessionDataKey(user, sessionID)] = sd
return nil
}
-func (identity *inMemoryIdentity) GetWebauthnSessionData(ctx context.Context, user, sessionID string) (*wantypes.SessionData, error) {
+func (identity *inMemoryIdentity) GetWebauthnSessionData(ctx context.Context, user, sessionID string) (*wanpb.SessionData, error) {
identity.mu.RLock()
defer identity.mu.RUnlock()
sd, ok := identity.sessionData[sessionDataKey(user, sessionID)]
@@ -126,7 +127,7 @@ type RegistrationFlow struct {
// resident key.
// As a side effect Begin may assign (and record in storage) a WebAuthn ID for
// the user.
-func (f *RegistrationFlow) Begin(ctx context.Context, user string, passwordless bool) (*CredentialCreation, error) {
+func (f *RegistrationFlow) Begin(ctx context.Context, user string, passwordless bool) (*wantypes.CredentialCreation, error) {
if user == "" {
return nil, trace.BadParameter("user required")
}
@@ -192,7 +193,7 @@ func (f *RegistrationFlow) Begin(ctx context.Context, user string, passwordless
return nil, trace.Wrap(err)
}
- return (*CredentialCreation)(cc), nil
+ return wantypes.CredentialCreationFromProtocol(cc), nil
}
func upsertOrGetWebID(ctx context.Context, user string, identity RegistrationIdentity) ([]byte, error) {
@@ -233,7 +234,7 @@ type RegisterResponse struct {
// DeviceName is the name for the new device.
DeviceName string
// CreationResponse is the response from the new device.
- CreationResponse *CredentialCreationResponse
+ CreationResponse *wantypes.CredentialCreationResponse
// Passwordless is true if this is expected to be a passwordless registration.
// Callers may make certain concessions when processing passwordless
// registration (such as skipping password validation), this flag reflects that.
@@ -349,7 +350,7 @@ func (f *RegistrationFlow) Finish(ctx context.Context, req RegisterResponse) (*t
return newDevice, nil
}
-func parseCredentialCreationResponse(resp *CredentialCreationResponse) (*protocol.ParsedCredentialCreationData, error) {
+func parseCredentialCreationResponse(resp *wantypes.CredentialCreationResponse) (*protocol.ParsedCredentialCreationData, error) {
// Remove extensions before marshaling, duo-labs/webauthn isn't expecting it.
exts := resp.Extensions
resp.Extensions = nil
diff --git a/lib/auth/webauthn/register_test.go b/lib/auth/webauthn/register_test.go
index f78fbb3fa1481..fd4292aab18a4 100644
--- a/lib/auth/webauthn/register_test.go
+++ b/lib/auth/webauthn/register_test.go
@@ -29,6 +29,7 @@ import (
"github.com/gravitational/teleport/api/types"
"github.com/gravitational/teleport/lib/auth/mocku2f"
wanlib "github.com/gravitational/teleport/lib/auth/webauthn"
+ wantypes "github.com/gravitational/teleport/lib/auth/webauthntypes"
)
func TestRegistrationFlow_BeginFinish(t *testing.T) {
@@ -197,9 +198,9 @@ func TestRegistrationFlow_Begin_excludeList(t *testing.T) {
return bytes.Compare(got[i].CredentialID, got[j].CredentialID) == -1
})
- want := make([]protocol.CredentialDescriptor, len(test.wantExcludeList))
+ want := make([]wantypes.CredentialDescriptor, len(test.wantExcludeList))
for i, id := range test.wantExcludeList {
- want[i] = protocol.CredentialDescriptor{
+ want[i] = wantypes.CredentialDescriptor{
Type: protocol.PublicKeyCredentialType,
CredentialID: id,
}
@@ -306,7 +307,7 @@ func TestRegistrationFlow_Finish_errors(t *testing.T) {
tests := []struct {
name string
user, deviceName string
- createResp func() *wanlib.CredentialCreationResponse
+ createResp func() *wantypes.CredentialCreationResponse
wantErr string
passwordless bool
}{
@@ -314,28 +315,28 @@ func TestRegistrationFlow_Finish_errors(t *testing.T) {
name: "NOK user empty",
user: "",
deviceName: "webauthn2",
- createResp: func() *wanlib.CredentialCreationResponse { return okCCR },
+ createResp: func() *wantypes.CredentialCreationResponse { return okCCR },
wantErr: "user required",
},
{
name: "NOK device name empty",
user: user,
deviceName: "",
- createResp: func() *wanlib.CredentialCreationResponse { return okCCR },
+ createResp: func() *wantypes.CredentialCreationResponse { return okCCR },
wantErr: "device name required",
},
{
name: "NOK credential response nil",
user: user,
deviceName: "webauthn2",
- createResp: func() *wanlib.CredentialCreationResponse { return nil },
+ createResp: func() *wantypes.CredentialCreationResponse { return nil },
wantErr: "response required",
},
{
name: "NOK credential with bad origin",
user: user,
deviceName: "webauthn2",
- createResp: func() *wanlib.CredentialCreationResponse {
+ createResp: func() *wantypes.CredentialCreationResponse {
resp, err := key.SignCredentialCreation("https://alpacasarerad.com" /* origin */, cc)
require.NoError(t, err)
return resp
@@ -346,7 +347,7 @@ func TestRegistrationFlow_Finish_errors(t *testing.T) {
name: "NOK credential with bad RPID",
user: user,
deviceName: "webauthn2",
- createResp: func() *wanlib.CredentialCreationResponse {
+ createResp: func() *wantypes.CredentialCreationResponse {
cc, err := webRegistration.Begin(ctx, user, false /* passwordless */)
require.NoError(t, err)
cc.Response.RelyingParty.ID = "badrpid.com"
@@ -361,7 +362,7 @@ func TestRegistrationFlow_Finish_errors(t *testing.T) {
name: "NOK credential with invalid signature",
user: user,
deviceName: "webauthn2",
- createResp: func() *wanlib.CredentialCreationResponse {
+ createResp: func() *wantypes.CredentialCreationResponse {
cc, err := webRegistration.Begin(ctx, user, false /* passwordless */)
require.NoError(t, err)
// Flip a challenge bit, this should be enough to consistently fail
@@ -379,7 +380,7 @@ func TestRegistrationFlow_Finish_errors(t *testing.T) {
user: user,
deviceName: "webauthn2",
passwordless: true,
- createResp: func() *wanlib.CredentialCreationResponse {
+ createResp: func() *wantypes.CredentialCreationResponse {
cc, err := webRegistration.Begin(ctx, user, false /* passwordless */)
require.NoError(t, err)
resp, err := key.SignCredentialCreation(webOrigin, cc)
@@ -393,7 +394,7 @@ func TestRegistrationFlow_Finish_errors(t *testing.T) {
user: user,
deviceName: "webauthn2",
passwordless: true,
- createResp: func() *wanlib.CredentialCreationResponse {
+ createResp: func() *wantypes.CredentialCreationResponse {
cc, err := webRegistration.Begin(ctx, user, true /* passwordless */)
require.NoError(t, err)
diff --git a/lib/auth/webauthn/session.go b/lib/auth/webauthn/session.go
index fc9dd129964b6..2928038e8087a 100644
--- a/lib/auth/webauthn/session.go
+++ b/lib/auth/webauthn/session.go
@@ -23,7 +23,7 @@ import (
wan "github.com/go-webauthn/webauthn/webauthn"
"github.com/gravitational/trace"
- wantypes "github.com/gravitational/teleport/api/types/webauthn"
+ wanpb "github.com/gravitational/teleport/api/types/webauthn"
)
// scopeLogin identifies session data stored for login.
@@ -37,13 +37,13 @@ const scopeLogin = "login"
// that use in-memory storage.
const scopeSession = "registration"
-func sessionToPB(sd *wan.SessionData) (*wantypes.SessionData, error) {
+func sessionToPB(sd *wan.SessionData) (*wanpb.SessionData, error) {
rawChallenge, err := base64.RawURLEncoding.DecodeString(sd.Challenge)
if err != nil {
return nil, trace.Wrap(err)
}
// TODO(codingllama): Record extensions in stored session data.
- return &wantypes.SessionData{
+ return &wanpb.SessionData{
Challenge: rawChallenge,
UserId: sd.UserID,
AllowCredentials: sd.AllowedCredentialIDs,
@@ -51,7 +51,7 @@ func sessionToPB(sd *wan.SessionData) (*wantypes.SessionData, error) {
}, nil
}
-func sessionFromPB(sd *wantypes.SessionData) *wan.SessionData {
+func sessionFromPB(sd *wanpb.SessionData) *wan.SessionData {
// TODO(codingllama): Record extensions in stored session data.
return &wan.SessionData{
Challenge: base64.RawURLEncoding.EncodeToString(sd.Challenge),
diff --git a/lib/auth/webauthncli/api.go b/lib/auth/webauthncli/api.go
index 08feab8305303..5ee83859dccce 100644
--- a/lib/auth/webauthncli/api.go
+++ b/lib/auth/webauthncli/api.go
@@ -24,8 +24,8 @@ import (
"github.com/gravitational/teleport/api/client/proto"
"github.com/gravitational/teleport/lib/auth/touchid"
- wanlib "github.com/gravitational/teleport/lib/auth/webauthn"
- "github.com/gravitational/teleport/lib/auth/webauthnwin"
+ wantypes "github.com/gravitational/teleport/lib/auth/webauthntypes"
+ wanwin "github.com/gravitational/teleport/lib/auth/webauthnwin"
)
// ErrUsingNonRegisteredDevice is returned from Login when the user attempts to
@@ -117,7 +117,7 @@ type LoginOpts struct {
// authentication and connected devices.
func Login(
ctx context.Context,
- origin string, assertion *wanlib.CredentialAssertion, prompt LoginPrompt, opts *LoginOpts,
+ origin string, assertion *wantypes.CredentialAssertion, prompt LoginPrompt, opts *LoginOpts,
) (*proto.MFAAuthenticateResponse, string, error) {
// origin vs RPID sanity check.
// Doesn't necessarily means a failure, but it's likely to be one.
@@ -137,10 +137,10 @@ func Login(
user = opts.User
}
- if webauthnwin.IsAvailable() {
+ if wanwin.IsAvailable() {
log.Debug("WebAuthnWin: Using windows webauthn for credential assertion")
- return webauthnwin.Login(ctx, origin, assertion, &webauthnwin.LoginOpts{
- AuthenticatorAttachment: webauthnwin.AuthenticatorAttachment(attachment),
+ return wanwin.Login(ctx, origin, assertion, &wanwin.LoginOpts{
+ AuthenticatorAttachment: wanwin.AuthenticatorAttachment(attachment),
})
}
@@ -165,7 +165,7 @@ func Login(
func crossPlatformLogin(
ctx context.Context,
- origin string, assertion *wanlib.CredentialAssertion, prompt LoginPrompt, opts *LoginOpts,
+ origin string, assertion *wantypes.CredentialAssertion, prompt LoginPrompt, opts *LoginOpts,
) (*proto.MFAAuthenticateResponse, string, error) {
if isLibfido2Enabled() {
log.Debug("FIDO2: Using libfido2 for assertion")
@@ -189,14 +189,14 @@ func crossPlatformLogin(
return resp, "" /* credentialUser */, err
}
-func platformLogin(origin, user string, assertion *wanlib.CredentialAssertion, prompt LoginPrompt) (*proto.MFAAuthenticateResponse, string, error) {
+func platformLogin(origin, user string, assertion *wantypes.CredentialAssertion, prompt LoginPrompt) (*proto.MFAAuthenticateResponse, string, error) {
resp, credentialUser, err := touchid.AttemptLogin(origin, user, assertion, ToTouchIDCredentialPicker(prompt))
if err != nil {
return nil, "", err
}
return &proto.MFAAuthenticateResponse{
Response: &proto.MFAAuthenticateResponse_Webauthn{
- Webauthn: wanlib.CredentialAssertionResponseToProto(resp),
+ Webauthn: wantypes.CredentialAssertionResponseToProto(resp),
},
}, credentialUser, nil
}
@@ -225,10 +225,10 @@ type RegisterPrompt interface {
// type of authentication and connected devices.
func Register(
ctx context.Context,
- origin string, cc *wanlib.CredentialCreation, prompt RegisterPrompt) (*proto.MFARegisterResponse, error) {
- if webauthnwin.IsAvailable() {
+ origin string, cc *wantypes.CredentialCreation, prompt RegisterPrompt) (*proto.MFARegisterResponse, error) {
+ if wanwin.IsAvailable() {
log.Debug("WebAuthnWin: Using windows webauthn for credential creation")
- return webauthnwin.Register(ctx, origin, cc)
+ return wanwin.Register(ctx, origin, cc)
}
if isLibfido2Enabled() {
@@ -258,5 +258,5 @@ func HasPlatformSupport() bool {
// IsFIDO2Available returns true if FIDO2 is implemented either via native
// libfido2 library or Windows WebAuthn API.
func IsFIDO2Available() bool {
- return isLibfido2Enabled() || webauthnwin.IsAvailable()
+ return isLibfido2Enabled() || wanwin.IsAvailable()
}
diff --git a/lib/auth/webauthncli/fido2.go b/lib/auth/webauthncli/fido2.go
index c2aa25d76d328..3e98416808260 100644
--- a/lib/auth/webauthncli/fido2.go
+++ b/lib/auth/webauthncli/fido2.go
@@ -37,7 +37,7 @@ import (
"github.com/gravitational/teleport/api/client/proto"
wanpb "github.com/gravitational/teleport/api/types/webauthn"
- wanlib "github.com/gravitational/teleport/lib/auth/webauthn"
+ wantypes "github.com/gravitational/teleport/lib/auth/webauthntypes"
)
// User-friendly device filter errors.
@@ -95,7 +95,7 @@ func isLibfido2Enabled() bool {
// fido2Login implements FIDO2Login.
func fido2Login(
ctx context.Context,
- origin string, assertion *wanlib.CredentialAssertion, prompt LoginPrompt, opts *LoginOpts,
+ origin string, assertion *wantypes.CredentialAssertion, prompt LoginPrompt, opts *LoginOpts,
) (*proto.MFAAuthenticateResponse, string, error) {
switch {
case origin == "":
@@ -131,7 +131,7 @@ func fido2Login(
rpID := assertion.Response.RelyingPartyID
var appID string
- if val, ok := assertion.Response.Extensions[wanlib.AppIDExtension]; ok {
+ if val, ok := assertion.Response.Extensions[wantypes.AppIDExtension]; ok {
appID = fmt.Sprint(val)
}
@@ -330,7 +330,7 @@ func pickAssertion(
// fido2Register implements FIDO2Register.
func fido2Register(
ctx context.Context,
- origin string, cc *wanlib.CredentialCreation, prompt RegisterPrompt,
+ origin string, cc *wantypes.CredentialCreation, prompt RegisterPrompt,
) (*proto.MFARegisterResponse, error) {
switch {
case origin == "":
@@ -380,7 +380,6 @@ func fido2Register(
ID: cc.Response.User.ID,
Name: cc.Response.User.Name,
DisplayName: cc.Response.User.DisplayName,
- Icon: cc.Response.User.Icon,
}
plat := cc.Response.AuthenticatorSelection.AuthenticatorAttachment == protocol.Platform
uv := cc.Response.AuthenticatorSelection.UserVerification == protocol.VerificationRequired
diff --git a/lib/auth/webauthncli/fido2_common.go b/lib/auth/webauthncli/fido2_common.go
index f77e42e4c26cc..e9ed61eda9a6f 100644
--- a/lib/auth/webauthncli/fido2_common.go
+++ b/lib/auth/webauthncli/fido2_common.go
@@ -24,7 +24,7 @@ import (
"github.com/gravitational/trace"
"github.com/gravitational/teleport/api/client/proto"
- wanlib "github.com/gravitational/teleport/lib/auth/webauthn"
+ wantypes "github.com/gravitational/teleport/lib/auth/webauthntypes"
)
// FIDO2PollInterval is the poll interval used to check for new FIDO2 devices.
@@ -41,7 +41,7 @@ var FIDO2PollInterval = 200 * time.Millisecond
// IsFIDO2Available.
func FIDO2Login(
ctx context.Context,
- origin string, assertion *wanlib.CredentialAssertion, prompt LoginPrompt, opts *LoginOpts,
+ origin string, assertion *wantypes.CredentialAssertion, prompt LoginPrompt, opts *LoginOpts,
) (*proto.MFAAuthenticateResponse, string, error) {
return fido2Login(ctx, origin, assertion, prompt, opts)
}
@@ -53,7 +53,7 @@ func FIDO2Login(
// IsFIDO2Available.
func FIDO2Register(
ctx context.Context,
- origin string, cc *wanlib.CredentialCreation, prompt RegisterPrompt,
+ origin string, cc *wantypes.CredentialCreation, prompt RegisterPrompt,
) (*proto.MFARegisterResponse, error) {
return fido2Register(ctx, origin, cc, prompt)
}
@@ -74,23 +74,23 @@ func FIDO2Diag(ctx context.Context, promptOut io.Writer) (*FIDO2DiagResult, erro
// Attempt registration.
const origin = "localhost"
- cc := &wanlib.CredentialCreation{
- Response: protocol.PublicKeyCredentialCreationOptions{
+ cc := &wantypes.CredentialCreation{
+ Response: wantypes.PublicKeyCredentialCreationOptions{
Challenge: make([]byte, 32),
- RelyingParty: protocol.RelyingPartyEntity{
- CredentialEntity: protocol.CredentialEntity{
+ RelyingParty: wantypes.RelyingPartyEntity{
+ CredentialEntity: wantypes.CredentialEntity{
Name: "localhost",
},
ID: "localhost",
},
- User: protocol.UserEntity{
- CredentialEntity: protocol.CredentialEntity{
+ User: wantypes.UserEntity{
+ CredentialEntity: wantypes.CredentialEntity{
Name: "test",
},
DisplayName: "test",
ID: []byte("test"),
},
- Parameters: []protocol.CredentialParameter{
+ Parameters: []wantypes.CredentialParameter{
{
Type: protocol.PublicKeyCredentialType,
Algorithm: webauthncose.AlgES256,
@@ -107,11 +107,11 @@ func FIDO2Diag(ctx context.Context, promptOut io.Writer) (*FIDO2DiagResult, erro
res.RegisterSuccessful = true
// Attempt login.
- assertion := &wanlib.CredentialAssertion{
- Response: protocol.PublicKeyCredentialRequestOptions{
+ assertion := &wantypes.CredentialAssertion{
+ Response: wantypes.PublicKeyCredentialRequestOptions{
Challenge: make([]byte, 32),
RelyingPartyID: cc.Response.RelyingParty.ID,
- AllowedCredentials: []protocol.CredentialDescriptor{
+ AllowedCredentials: []wantypes.CredentialDescriptor{
{
Type: protocol.PublicKeyCredentialType,
CredentialID: ccr.GetWebauthn().GetRawId(),
diff --git a/lib/auth/webauthncli/fido2_other.go b/lib/auth/webauthncli/fido2_other.go
index 4b2505f4a67d6..be014196559c6 100644
--- a/lib/auth/webauthncli/fido2_other.go
+++ b/lib/auth/webauthncli/fido2_other.go
@@ -22,7 +22,7 @@ import (
"errors"
"github.com/gravitational/teleport/api/client/proto"
- wanlib "github.com/gravitational/teleport/lib/auth/webauthn"
+ wantypes "github.com/gravitational/teleport/lib/auth/webauthntypes"
)
var errFIDO2Unavailable = errors.New("FIDO2 unavailable in current build")
@@ -34,14 +34,14 @@ func isLibfido2Enabled() bool {
func fido2Login(
ctx context.Context,
- origin string, assertion *wanlib.CredentialAssertion, prompt LoginPrompt, opts *LoginOpts,
+ origin string, assertion *wantypes.CredentialAssertion, prompt LoginPrompt, opts *LoginOpts,
) (*proto.MFAAuthenticateResponse, string, error) {
return nil, "", errFIDO2Unavailable
}
func fido2Register(
ctx context.Context,
- origin string, cc *wanlib.CredentialCreation, prompt RegisterPrompt,
+ origin string, cc *wantypes.CredentialCreation, prompt RegisterPrompt,
) (*proto.MFARegisterResponse, error) {
return nil, errFIDO2Unavailable
}
diff --git a/lib/auth/webauthncli/fido2_test.go b/lib/auth/webauthncli/fido2_test.go
index 7b6ec46acd8a0..558b9b409093a 100644
--- a/lib/auth/webauthncli/fido2_test.go
+++ b/lib/auth/webauthncli/fido2_test.go
@@ -40,6 +40,7 @@ import (
"github.com/gravitational/teleport/lib/auth/mocku2f"
wanlib "github.com/gravitational/teleport/lib/auth/webauthn"
wancli "github.com/gravitational/teleport/lib/auth/webauthncli"
+ wantypes "github.com/gravitational/teleport/lib/auth/webauthntypes"
)
var (
@@ -243,14 +244,14 @@ func TestFIDO2Login(t *testing.T) {
legacy1 := mustNewFIDO2Device("/legacy1", "" /* pin */, &libfido2.DeviceInfo{Options: authOpts})
legacy1.wantRPID = appID
- challenge, err := protocol.CreateChallenge()
+ challenge, err := wantypes.CreateChallenge()
require.NoError(t, err, "CreateChallenge failed")
- baseAssertion := &wanlib.CredentialAssertion{
- Response: protocol.PublicKeyCredentialRequestOptions{
+ baseAssertion := &wantypes.CredentialAssertion{
+ Response: wantypes.PublicKeyCredentialRequestOptions{
Challenge: challenge,
RelyingPartyID: rpID,
- AllowedCredentials: []protocol.CredentialDescriptor{},
+ AllowedCredentials: []wantypes.CredentialDescriptor{},
UserVerification: protocol.VerificationDiscouraged,
Extensions: map[string]interface{}{},
},
@@ -261,7 +262,7 @@ func TestFIDO2Login(t *testing.T) {
timeout time.Duration
fido2 *fakeFIDO2
setUP func()
- createAssertion func() *wanlib.CredentialAssertion
+ createAssertion func() *wantypes.CredentialAssertion
prompt wancli.LoginPrompt
opts *wancli.LoginOpts
// assertResponse and wantErr are mutually exclusive.
@@ -279,9 +280,9 @@ func TestFIDO2Login(t *testing.T) {
auth1.setUP()
}()
},
- createAssertion: func() *wanlib.CredentialAssertion {
+ createAssertion: func() *wantypes.CredentialAssertion {
cp := *baseAssertion
- cp.Response.AllowedCredentials = []protocol.CredentialDescriptor{
+ cp.Response.AllowedCredentials = []wantypes.CredentialDescriptor{
{CredentialID: auth1.credentialID()},
}
return &cp
@@ -294,9 +295,9 @@ func TestFIDO2Login(t *testing.T) {
name: "pin protected device",
fido2: newFakeFIDO2(pin1),
setUP: pin1.setUP,
- createAssertion: func() *wanlib.CredentialAssertion {
+ createAssertion: func() *wantypes.CredentialAssertion {
cp := *baseAssertion
- cp.Response.AllowedCredentials = []protocol.CredentialDescriptor{
+ cp.Response.AllowedCredentials = []wantypes.CredentialDescriptor{
{CredentialID: pin1.credentialID()},
}
return &cp
@@ -306,9 +307,9 @@ func TestFIDO2Login(t *testing.T) {
name: "biometric device",
fido2: newFakeFIDO2(bio1),
setUP: bio1.setUP,
- createAssertion: func() *wanlib.CredentialAssertion {
+ createAssertion: func() *wantypes.CredentialAssertion {
cp := *baseAssertion
- cp.Response.AllowedCredentials = []protocol.CredentialDescriptor{
+ cp.Response.AllowedCredentials = []wantypes.CredentialDescriptor{
{CredentialID: bio1.credentialID()},
}
return &cp
@@ -318,13 +319,13 @@ func TestFIDO2Login(t *testing.T) {
name: "legacy device (AppID)",
fido2: newFakeFIDO2(legacy1),
setUP: legacy1.setUP,
- createAssertion: func() *wanlib.CredentialAssertion {
+ createAssertion: func() *wantypes.CredentialAssertion {
cp := *baseAssertion
- cp.Response.AllowedCredentials = []protocol.CredentialDescriptor{
+ cp.Response.AllowedCredentials = []wantypes.CredentialDescriptor{
{CredentialID: legacy1.credentialID()},
}
- cp.Response.Extensions = protocol.AuthenticationExtensions{
- wanlib.AppIDExtension: appID,
+ cp.Response.Extensions = wantypes.AuthenticationExtensions{
+ wantypes.AppIDExtension: appID,
}
return &cp
},
@@ -341,16 +342,16 @@ func TestFIDO2Login(t *testing.T) {
legacy1,
),
setUP: bio1.setUP,
- createAssertion: func() *wanlib.CredentialAssertion {
+ createAssertion: func() *wantypes.CredentialAssertion {
cp := *baseAssertion
- cp.Response.AllowedCredentials = []protocol.CredentialDescriptor{
+ cp.Response.AllowedCredentials = []wantypes.CredentialDescriptor{
{CredentialID: auth1.credentialID()},
{CredentialID: pin1.credentialID()},
{CredentialID: bio1.credentialID()},
{CredentialID: legacy1.credentialID()},
}
- cp.Response.Extensions = protocol.AuthenticationExtensions{
- wanlib.AppIDExtension: appID,
+ cp.Response.Extensions = wantypes.AuthenticationExtensions{
+ wantypes.AppIDExtension: appID,
}
return &cp
},
@@ -367,15 +368,15 @@ func TestFIDO2Login(t *testing.T) {
legacy1, // doesn't match RPID or AppID
),
setUP: auth1.setUP,
- createAssertion: func() *wanlib.CredentialAssertion {
+ createAssertion: func() *wantypes.CredentialAssertion {
cp := *baseAssertion
- cp.Response.AllowedCredentials = []protocol.CredentialDescriptor{
+ cp.Response.AllowedCredentials = []wantypes.CredentialDescriptor{
{CredentialID: auth1.credentialID()},
{CredentialID: bio1.credentialID()},
{CredentialID: legacy1.credentialID()},
}
- cp.Response.Extensions = protocol.AuthenticationExtensions{
- wanlib.AppIDExtension: "https://badexample.com",
+ cp.Response.Extensions = wantypes.AuthenticationExtensions{
+ wantypes.AppIDExtension: "https://badexample.com",
}
return &cp
},
@@ -391,9 +392,9 @@ func TestFIDO2Login(t *testing.T) {
bio1,
),
setUP: pin2.setUP,
- createAssertion: func() *wanlib.CredentialAssertion {
+ createAssertion: func() *wantypes.CredentialAssertion {
cp := *baseAssertion
- cp.Response.AllowedCredentials = []protocol.CredentialDescriptor{
+ cp.Response.AllowedCredentials = []wantypes.CredentialDescriptor{
{CredentialID: auth1.credentialID()},
{CredentialID: pin1.credentialID()},
{CredentialID: pin2.credentialID()},
@@ -410,9 +411,9 @@ func TestFIDO2Login(t *testing.T) {
timeout: 10 * time.Millisecond,
fido2: newFakeFIDO2(),
setUP: func() {},
- createAssertion: func() *wanlib.CredentialAssertion {
+ createAssertion: func() *wantypes.CredentialAssertion {
cp := *baseAssertion
- cp.Response.AllowedCredentials = []protocol.CredentialDescriptor{
+ cp.Response.AllowedCredentials = []wantypes.CredentialDescriptor{
{CredentialID: auth1.credentialID()},
}
return &cp
@@ -424,9 +425,9 @@ func TestFIDO2Login(t *testing.T) {
timeout: 10 * time.Millisecond,
fido2: newFakeFIDO2(auth1, pin1, bio1, legacy1),
setUP: func() {}, // no interaction
- createAssertion: func() *wanlib.CredentialAssertion {
+ createAssertion: func() *wantypes.CredentialAssertion {
cp := *baseAssertion
- cp.Response.AllowedCredentials = []protocol.CredentialDescriptor{
+ cp.Response.AllowedCredentials = []wantypes.CredentialDescriptor{
{CredentialID: auth1.credentialID()},
{CredentialID: pin1.credentialID()},
{CredentialID: bio1.credentialID()},
@@ -440,9 +441,9 @@ func TestFIDO2Login(t *testing.T) {
timeout: 10 * time.Millisecond,
fido2: newFakeFIDO2(auth1, pin1),
setUP: func() {}, // no interaction
- createAssertion: func() *wanlib.CredentialAssertion {
+ createAssertion: func() *wantypes.CredentialAssertion {
cp := *baseAssertion
- cp.Response.AllowedCredentials = []protocol.CredentialDescriptor{
+ cp.Response.AllowedCredentials = []wantypes.CredentialDescriptor{
{CredentialID: auth1.credentialID()},
}
return &cp
@@ -454,7 +455,7 @@ func TestFIDO2Login(t *testing.T) {
fido2: newFakeFIDO2(pin3, bio2), // pin3 and bio2 have resident credentials
setUP: pin3.setUP, // user chooses pin3, but cancels before further touches
prompt: &pinCancelPrompt{pin: pin3.pin}, // cancel set on test body
- createAssertion: func() *wanlib.CredentialAssertion {
+ createAssertion: func() *wantypes.CredentialAssertion {
cp := *baseAssertion
cp.Response.AllowedCredentials = nil // passwordless forces PIN
cp.Response.UserVerification = protocol.VerificationRequired
@@ -466,7 +467,7 @@ func TestFIDO2Login(t *testing.T) {
name: "passwordless pin",
fido2: newFakeFIDO2(pin3),
setUP: pin3.setUP,
- createAssertion: func() *wanlib.CredentialAssertion {
+ createAssertion: func() *wantypes.CredentialAssertion {
cp := *baseAssertion
cp.Response.AllowedCredentials = nil
cp.Response.UserVerification = protocol.VerificationRequired
@@ -483,7 +484,7 @@ func TestFIDO2Login(t *testing.T) {
name: "passwordless biometric (llama)",
fido2: newFakeFIDO2(bio2),
setUP: bio2.setUP,
- createAssertion: func() *wanlib.CredentialAssertion {
+ createAssertion: func() *wantypes.CredentialAssertion {
cp := *baseAssertion
cp.Response.AllowedCredentials = nil
cp.Response.UserVerification = protocol.VerificationRequired
@@ -503,7 +504,7 @@ func TestFIDO2Login(t *testing.T) {
name: "passwordless biometric (alpaca)",
fido2: newFakeFIDO2(bio2),
setUP: bio2.setUP,
- createAssertion: func() *wanlib.CredentialAssertion {
+ createAssertion: func() *wantypes.CredentialAssertion {
cp := *baseAssertion
cp.Response.AllowedCredentials = nil
cp.Response.UserVerification = protocol.VerificationRequired
@@ -523,7 +524,7 @@ func TestFIDO2Login(t *testing.T) {
name: "passwordless single-choice credential picker",
fido2: newFakeFIDO2(pin3),
setUP: pin3.setUP,
- createAssertion: func() *wanlib.CredentialAssertion {
+ createAssertion: func() *wantypes.CredentialAssertion {
cp := *baseAssertion
cp.Response.AllowedCredentials = nil
cp.Response.UserVerification = protocol.VerificationRequired
@@ -540,7 +541,7 @@ func TestFIDO2Login(t *testing.T) {
name: "passwordless multi-choice credential picker",
fido2: newFakeFIDO2(bio2),
setUP: bio2.setUP,
- createAssertion: func() *wanlib.CredentialAssertion {
+ createAssertion: func() *wantypes.CredentialAssertion {
cp := *baseAssertion
cp.Response.AllowedCredentials = nil
cp.Response.UserVerification = protocol.VerificationRequired
@@ -557,7 +558,7 @@ func TestFIDO2Login(t *testing.T) {
name: "NOK passwordless no credentials",
fido2: newFakeFIDO2(bio1),
setUP: bio1.setUP,
- createAssertion: func() *wanlib.CredentialAssertion {
+ createAssertion: func() *wantypes.CredentialAssertion {
cp := *baseAssertion
cp.Response.AllowedCredentials = nil
cp.Response.UserVerification = protocol.VerificationRequired
@@ -570,7 +571,7 @@ func TestFIDO2Login(t *testing.T) {
name: "NOK passwordless unknown user",
fido2: newFakeFIDO2(bio2),
setUP: bio2.setUP,
- createAssertion: func() *wanlib.CredentialAssertion {
+ createAssertion: func() *wantypes.CredentialAssertion {
cp := *baseAssertion
cp.Response.AllowedCredentials = nil
cp.Response.UserVerification = protocol.VerificationRequired
@@ -691,8 +692,8 @@ func TestFIDO2Login_retryUVFailures(t *testing.T) {
const rpID = "example.com"
const origin = "https://example.com"
ctx := context.Background()
- assertion := &wanlib.CredentialAssertion{
- Response: protocol.PublicKeyCredentialRequestOptions{
+ assertion := &wantypes.CredentialAssertion{
+ Response: wantypes.PublicKeyCredentialRequestOptions{
Challenge: []byte{1, 2, 3, 4, 5}, // arbitrary
RelyingPartyID: rpID,
UserVerification: protocol.VerificationRequired,
@@ -745,8 +746,8 @@ func TestFIDO2Login_singleResidentCredential(t *testing.T) {
const rpID = "example.com"
const origin = "https://example.com"
ctx := context.Background()
- assertion := &wanlib.CredentialAssertion{
- Response: protocol.PublicKeyCredentialRequestOptions{
+ assertion := &wantypes.CredentialAssertion{
+ Response: wantypes.PublicKeyCredentialRequestOptions{
Challenge: []byte{1, 2, 3, 4, 5}, // arbitrary
RelyingPartyID: rpID,
UserVerification: protocol.VerificationRequired,
@@ -862,11 +863,11 @@ func TestFIDO2Login_PromptTouch(t *testing.T) {
},
})
- mfaAssertion := &wanlib.CredentialAssertion{
- Response: protocol.PublicKeyCredentialRequestOptions{
+ mfaAssertion := &wantypes.CredentialAssertion{
+ Response: wantypes.PublicKeyCredentialRequestOptions{
Challenge: make([]byte, 32),
RelyingPartyID: rpID,
- AllowedCredentials: []protocol.CredentialDescriptor{
+ AllowedCredentials: []wantypes.CredentialDescriptor{
{
Type: protocol.PublicKeyCredentialType,
CredentialID: auth1.credentialID(),
@@ -882,8 +883,8 @@ func TestFIDO2Login_PromptTouch(t *testing.T) {
},
},
}
- pwdlessAssertion := &wanlib.CredentialAssertion{
- Response: protocol.PublicKeyCredentialRequestOptions{
+ pwdlessAssertion := &wantypes.CredentialAssertion{
+ Response: wantypes.PublicKeyCredentialRequestOptions{
Challenge: make([]byte, 32),
RelyingPartyID: rpID,
UserVerification: protocol.VerificationRequired,
@@ -893,7 +894,7 @@ func TestFIDO2Login_PromptTouch(t *testing.T) {
tests := []struct {
name string
fido2 *fakeFIDO2
- assertion *wanlib.CredentialAssertion
+ assertion *wantypes.CredentialAssertion
prompt wancli.LoginPrompt
opts *wancli.LoginOpts
wantTouches int
@@ -971,29 +972,29 @@ func TestFIDO2Login_u2fDevice(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
- cc := &wanlib.CredentialCreation{
- Response: protocol.PublicKeyCredentialCreationOptions{
+ cc := &wantypes.CredentialCreation{
+ Response: wantypes.PublicKeyCredentialCreationOptions{
Challenge: []byte{1, 2, 3, 4, 5}, // arbitrary
- RelyingParty: protocol.RelyingPartyEntity{
+ RelyingParty: wantypes.RelyingPartyEntity{
ID: rpID,
- CredentialEntity: protocol.CredentialEntity{
+ CredentialEntity: wantypes.CredentialEntity{
Name: "rp name",
},
},
- Parameters: []protocol.CredentialParameter{
+ Parameters: []wantypes.CredentialParameter{
{
Type: protocol.PublicKeyCredentialType,
Algorithm: webauthncose.AlgES256,
},
},
- User: protocol.UserEntity{
+ User: wantypes.UserEntity{
ID: []byte{1, 2, 3, 4, 1}, // arbitrary,
- CredentialEntity: protocol.CredentialEntity{
+ CredentialEntity: wantypes.CredentialEntity{
Name: "user name",
},
DisplayName: "user display name",
},
- AuthenticatorSelection: protocol.AuthenticatorSelection{
+ AuthenticatorSelection: wantypes.AuthenticatorSelection{
UserVerification: protocol.VerificationDiscouraged,
},
Attestation: protocol.PreferNoAttestation,
@@ -1004,11 +1005,11 @@ func TestFIDO2Login_u2fDevice(t *testing.T) {
ccr, err := wancli.FIDO2Register(ctx, origin, cc, dev /* prompt */)
require.NoError(t, err, "FIDO2Register errored")
- assertion := &wanlib.CredentialAssertion{
- Response: protocol.PublicKeyCredentialRequestOptions{
+ assertion := &wantypes.CredentialAssertion{
+ Response: wantypes.PublicKeyCredentialRequestOptions{
Challenge: []byte{1, 2, 3, 4, 5}, // arbitrary
RelyingPartyID: rpID,
- AllowedCredentials: []protocol.CredentialDescriptor{
+ AllowedCredentials: []wantypes.CredentialDescriptor{
{
Type: protocol.PublicKeyCredentialType,
CredentialID: ccr.GetWebauthn().GetRawId(),
@@ -1042,8 +1043,8 @@ func TestFIDO2Login_bioErrorHandling(t *testing.T) {
// Prepare a passwordless assertion.
// MFA would do as well; both are realistic here.
const origin = "https://example.com"
- assertion := &wanlib.CredentialAssertion{
- Response: protocol.PublicKeyCredentialRequestOptions{
+ assertion := &wantypes.CredentialAssertion{
+ Response: wantypes.PublicKeyCredentialRequestOptions{
Challenge: []byte{1, 2, 3, 4, 5},
RelyingPartyID: "example.com",
AllowedCredentials: nil, // passwordless
@@ -1128,11 +1129,11 @@ func TestFIDO2Login_errors(t *testing.T) {
f2.setCallbacks()
const origin = "https://example.com"
- okAssertion := &wanlib.CredentialAssertion{
- Response: protocol.PublicKeyCredentialRequestOptions{
+ okAssertion := &wantypes.CredentialAssertion{
+ Response: wantypes.PublicKeyCredentialRequestOptions{
Challenge: make([]byte, 32),
RelyingPartyID: "example.com",
- AllowedCredentials: []protocol.CredentialDescriptor{
+ AllowedCredentials: []wantypes.CredentialDescriptor{
{Type: protocol.PublicKeyCredentialType, CredentialID: []byte{1, 2, 3, 4, 5}},
},
},
@@ -1148,7 +1149,7 @@ func TestFIDO2Login_errors(t *testing.T) {
tests := []struct {
name string
origin string
- assertion *wanlib.CredentialAssertion
+ assertion *wantypes.CredentialAssertion
prompt wancli.LoginPrompt
wantErr string
}{
@@ -1222,29 +1223,29 @@ func TestFIDO2_LoginRegister_interactionErrors(t *testing.T) {
const rpID = "goteleport.com"
const origin = "https://goteleport.com"
- mfaCC := &wanlib.CredentialCreation{
- Response: protocol.PublicKeyCredentialCreationOptions{
+ mfaCC := &wantypes.CredentialCreation{
+ Response: wantypes.PublicKeyCredentialCreationOptions{
Challenge: []byte{1, 2, 3, 4, 5}, // arbitrary
- RelyingParty: protocol.RelyingPartyEntity{
- CredentialEntity: protocol.CredentialEntity{
+ RelyingParty: wantypes.RelyingPartyEntity{
+ CredentialEntity: wantypes.CredentialEntity{
Name: "Teleport",
},
ID: rpID,
},
- User: protocol.UserEntity{
- CredentialEntity: protocol.CredentialEntity{
+ User: wantypes.UserEntity{
+ CredentialEntity: wantypes.CredentialEntity{
Name: "llama",
},
DisplayName: "Llama",
ID: []byte{1, 1, 1, 1, 1}, // arbitrary
},
- Parameters: []protocol.CredentialParameter{
+ Parameters: []wantypes.CredentialParameter{
{
Type: protocol.PublicKeyCredentialType,
Algorithm: webauthncose.AlgES256,
},
},
- AuthenticatorSelection: protocol.AuthenticatorSelection{
+ AuthenticatorSelection: wantypes.AuthenticatorSelection{
RequireResidentKey: protocol.ResidentKeyNotRequired(),
ResidentKey: protocol.ResidentKeyRequirementDiscouraged,
UserVerification: protocol.VerificationDiscouraged,
@@ -1265,15 +1266,15 @@ func TestFIDO2_LoginRegister_interactionErrors(t *testing.T) {
registeredCreds = append(registeredCreds, resp.GetWebauthn().RawId)
}
- mfaAssertion := &wanlib.CredentialAssertion{
- Response: protocol.PublicKeyCredentialRequestOptions{
+ mfaAssertion := &wantypes.CredentialAssertion{
+ Response: wantypes.PublicKeyCredentialRequestOptions{
Challenge: []byte{1, 2, 3, 4, 5}, // arbitrary
RelyingPartyID: rpID,
UserVerification: protocol.VerificationDiscouraged,
},
}
for _, cred := range registeredCreds {
- mfaAssertion.Response.AllowedCredentials = append(mfaAssertion.Response.AllowedCredentials, protocol.CredentialDescriptor{
+ mfaAssertion.Response.AllowedCredentials = append(mfaAssertion.Response.AllowedCredentials, wantypes.CredentialDescriptor{
Type: protocol.PublicKeyCredentialType,
CredentialID: cred,
})
@@ -1286,20 +1287,20 @@ func TestFIDO2_LoginRegister_interactionErrors(t *testing.T) {
// FIDO2Login interaction tests.
for _, test := range []struct {
name string
- createAssertion func() *wanlib.CredentialAssertion
+ createAssertion func() *wantypes.CredentialAssertion
prompt wancli.LoginPrompt
wantErr string
}{
{
name: "no registered credential",
- createAssertion: func() *wanlib.CredentialAssertion { return mfaAssertion },
+ createAssertion: func() *wantypes.CredentialAssertion { return mfaAssertion },
prompt: notRegistered,
wantErr: wancli.ErrUsingNonRegisteredDevice.Error(),
},
{
// Theoretically could happen, but not something we do today.
name: "mfa lacks UV",
- createAssertion: func() *wanlib.CredentialAssertion {
+ createAssertion: func() *wantypes.CredentialAssertion {
mfaUV := *mfaAssertion
mfaUV.Response.UserVerification = protocol.VerificationRequired
return &mfaUV
@@ -1309,20 +1310,20 @@ func TestFIDO2_LoginRegister_interactionErrors(t *testing.T) {
},
{
name: "passwordless lacks UV",
- createAssertion: func() *wanlib.CredentialAssertion { return &pwdlessAssertion },
+ createAssertion: func() *wantypes.CredentialAssertion { return &pwdlessAssertion },
prompt: noPIN, // PIN unset means it cannot do UV
wantErr: "passwordless",
},
{
// Fictional scenario, no real-world authenticators match.
name: "passwordless lacks RK",
- createAssertion: func() *wanlib.CredentialAssertion { return &pwdlessAssertion },
+ createAssertion: func() *wantypes.CredentialAssertion { return &pwdlessAssertion },
prompt: noRK,
wantErr: "passwordless",
},
{
name: "passwordless U2F",
- createAssertion: func() *wanlib.CredentialAssertion { return &pwdlessAssertion },
+ createAssertion: func() *wantypes.CredentialAssertion { return &pwdlessAssertion },
prompt: u2f,
wantErr: context.DeadlineExceeded.Error(), // silently filtered, times out
},
@@ -1338,7 +1339,7 @@ func TestFIDO2_LoginRegister_interactionErrors(t *testing.T) {
excludeCC := *mfaCC
for _, cred := range registeredCreds {
- excludeCC.Response.CredentialExcludeList = append(excludeCC.Response.CredentialExcludeList, protocol.CredentialDescriptor{
+ excludeCC.Response.CredentialExcludeList = append(excludeCC.Response.CredentialExcludeList, wantypes.CredentialDescriptor{
Type: protocol.PublicKeyCredentialType,
CredentialID: cred,
})
@@ -1352,38 +1353,38 @@ func TestFIDO2_LoginRegister_interactionErrors(t *testing.T) {
// FIDO2Register interaction tests.
for _, test := range []struct {
name string
- createCC func() *wanlib.CredentialCreation
+ createCC func() *wantypes.CredentialCreation
prompt wancli.RegisterPrompt
wantErr string
}{
{
name: "excluded credential",
- createCC: func() *wanlib.CredentialCreation { return &excludeCC },
+ createCC: func() *wantypes.CredentialCreation { return &excludeCC },
prompt: noPIN,
wantErr: "registered credential",
},
{
name: "excluded credential (U2F)",
- createCC: func() *wanlib.CredentialCreation { return &excludeCC },
+ createCC: func() *wantypes.CredentialCreation { return &excludeCC },
prompt: u2f,
wantErr: context.DeadlineExceeded.Error(), // silently filtered, times out
},
{
name: "passwordless lacks UV",
- createCC: func() *wanlib.CredentialCreation { return &pwdlessCC },
+ createCC: func() *wantypes.CredentialCreation { return &pwdlessCC },
prompt: noPIN, // PIN unset means it cannot do UV
wantErr: "user verification",
},
{
// Fictional scenario, no real-world authenticators match.
name: "passwordless lacks RK",
- createCC: func() *wanlib.CredentialCreation { return &pwdlessCC },
+ createCC: func() *wantypes.CredentialCreation { return &pwdlessCC },
prompt: noRK,
wantErr: "resident key",
},
{
name: "passwordless U2F",
- createCC: func() *wanlib.CredentialCreation { return &pwdlessCC },
+ createCC: func() *wantypes.CredentialCreation { return &pwdlessCC },
prompt: u2f,
wantErr: context.DeadlineExceeded.Error(), // silently filtered, times out
},
@@ -1435,25 +1436,25 @@ func TestFIDO2Register(t *testing.T) {
none1 := mustNewFIDO2Device("/none1", "" /* pin */, &libfido2.DeviceInfo{Options: authOpts})
none1.format = "none"
- challenge, err := protocol.CreateChallenge()
+ challenge, err := wantypes.CreateChallenge()
require.NoError(t, err, "CreateChallenge failed")
- baseCC := &wanlib.CredentialCreation{
- Response: protocol.PublicKeyCredentialCreationOptions{
+ baseCC := &wantypes.CredentialCreation{
+ Response: wantypes.PublicKeyCredentialCreationOptions{
Challenge: challenge,
- RelyingParty: protocol.RelyingPartyEntity{
+ RelyingParty: wantypes.RelyingPartyEntity{
ID: rpID,
- CredentialEntity: protocol.CredentialEntity{
+ CredentialEntity: wantypes.CredentialEntity{
Name: "rp name",
},
},
- Parameters: []protocol.CredentialParameter{
+ Parameters: []wantypes.CredentialParameter{
{Type: protocol.PublicKeyCredentialType, Algorithm: webauthncose.AlgES256},
},
- AuthenticatorSelection: protocol.AuthenticatorSelection{
+ AuthenticatorSelection: wantypes.AuthenticatorSelection{
UserVerification: protocol.VerificationDiscouraged,
},
- User: protocol.UserEntity{
+ User: wantypes.UserEntity{
ID: []byte{1, 2, 3, 4, 1}, // arbitrary,
CredentialEntity: protocol.CredentialEntity{
Name: "user name",
@@ -1465,8 +1466,8 @@ func TestFIDO2Register(t *testing.T) {
}
pwdlessCC := *baseCC
pwdlessCC.Response.RelyingParty.Name = "Teleport"
- pwdlessCC.Response.User = protocol.UserEntity{
- CredentialEntity: protocol.CredentialEntity{
+ pwdlessCC.Response.User = wantypes.UserEntity{
+ CredentialEntity: wantypes.CredentialEntity{
Name: "llama",
},
DisplayName: "Llama",
@@ -1481,7 +1482,7 @@ func TestFIDO2Register(t *testing.T) {
timeout time.Duration
fido2 *fakeFIDO2
setUP func()
- createCredential func() *wanlib.CredentialCreation
+ createCredential func() *wantypes.CredentialCreation
prompt wancli.RegisterPrompt
wantErr error
assertResponse func(t *testing.T, ccr *wanpb.CredentialCreationResponse, attObj *protocol.AttestationObject)
@@ -1490,7 +1491,7 @@ func TestFIDO2Register(t *testing.T) {
name: "single device, packed attestation",
fido2: newFakeFIDO2(auth1),
setUP: auth1.setUP,
- createCredential: func() *wanlib.CredentialCreation {
+ createCredential: func() *wantypes.CredentialCreation {
cp := *baseCC
return &cp
},
@@ -1514,7 +1515,7 @@ func TestFIDO2Register(t *testing.T) {
name: "fido-u2f attestation",
fido2: newFakeFIDO2(u2f1),
setUP: u2f1.setUP,
- createCredential: func() *wanlib.CredentialCreation {
+ createCredential: func() *wantypes.CredentialCreation {
cp := *baseCC
return &cp
},
@@ -1535,7 +1536,7 @@ func TestFIDO2Register(t *testing.T) {
name: "none attestation",
fido2: newFakeFIDO2(none1),
setUP: none1.setUP,
- createCredential: func() *wanlib.CredentialCreation {
+ createCredential: func() *wantypes.CredentialCreation {
cp := *baseCC
return &cp
},
@@ -1547,7 +1548,7 @@ func TestFIDO2Register(t *testing.T) {
name: "pin device",
fido2: newFakeFIDO2(pin1),
setUP: pin1.setUP,
- createCredential: func() *wanlib.CredentialCreation {
+ createCredential: func() *wantypes.CredentialCreation {
cp := *baseCC
return &cp
},
@@ -1557,7 +1558,7 @@ func TestFIDO2Register(t *testing.T) {
name: "multiple valid devices",
fido2: newFakeFIDO2(auth1, pin1, pin2, bio1),
setUP: bio1.setUP,
- createCredential: func() *wanlib.CredentialCreation {
+ createCredential: func() *wantypes.CredentialCreation {
cp := *baseCC
return &cp
},
@@ -1569,7 +1570,7 @@ func TestFIDO2Register(t *testing.T) {
name: "multiple devices, uses pin",
fido2: newFakeFIDO2(auth1, pin1, pin2, bio1),
setUP: pin2.setUP,
- createCredential: func() *wanlib.CredentialCreation {
+ createCredential: func() *wantypes.CredentialCreation {
cp := *baseCC
return &cp
},
@@ -1582,9 +1583,9 @@ func TestFIDO2Register(t *testing.T) {
name: "excluded devices, single valid",
fido2: newFakeFIDO2(auth1, bio1),
setUP: bio1.setUP,
- createCredential: func() *wanlib.CredentialCreation {
+ createCredential: func() *wantypes.CredentialCreation {
cp := *baseCC
- cp.Response.CredentialExcludeList = []protocol.CredentialDescriptor{
+ cp.Response.CredentialExcludeList = []wantypes.CredentialDescriptor{
{
Type: protocol.PublicKeyCredentialType,
CredentialID: auth1.credentialID(),
@@ -1600,9 +1601,9 @@ func TestFIDO2Register(t *testing.T) {
name: "excluded devices, multiple valid",
fido2: newFakeFIDO2(auth1, pin1, pin2, bio1),
setUP: bio1.setUP,
- createCredential: func() *wanlib.CredentialCreation {
+ createCredential: func() *wantypes.CredentialCreation {
cp := *baseCC
- cp.Response.CredentialExcludeList = []protocol.CredentialDescriptor{
+ cp.Response.CredentialExcludeList = []wantypes.CredentialDescriptor{
{
Type: protocol.PublicKeyCredentialType,
CredentialID: pin1.credentialID(),
@@ -1623,7 +1624,7 @@ func TestFIDO2Register(t *testing.T) {
timeout: 10 * time.Millisecond,
fido2: newFakeFIDO2(),
setUP: func() {},
- createCredential: func() *wanlib.CredentialCreation {
+ createCredential: func() *wantypes.CredentialCreation {
cp := *baseCC
return &cp
},
@@ -1633,7 +1634,7 @@ func TestFIDO2Register(t *testing.T) {
name: "passwordless pin device",
fido2: newFakeFIDO2(pin2),
setUP: pin2.setUP,
- createCredential: func() *wanlib.CredentialCreation {
+ createCredential: func() *wantypes.CredentialCreation {
cp := pwdlessCC
return &cp
},
@@ -1648,7 +1649,7 @@ func TestFIDO2Register(t *testing.T) {
name: "passwordless bio device",
fido2: newFakeFIDO2(bio1),
setUP: bio1.setUP,
- createCredential: func() *wanlib.CredentialCreation {
+ createCredential: func() *wantypes.CredentialCreation {
cp := pwdlessCC
return &cp
},
@@ -1663,7 +1664,7 @@ func TestFIDO2Register(t *testing.T) {
name: "passwordless ResidentKey=required",
fido2: newFakeFIDO2(pin2),
setUP: pin2.setUP,
- createCredential: func() *wanlib.CredentialCreation {
+ createCredential: func() *wantypes.CredentialCreation {
cp := pwdlessCC
cp.Response.AuthenticatorSelection.RequireResidentKey = nil
cp.Response.AuthenticatorSelection.ResidentKey = protocol.ResidentKeyRequirementRequired
@@ -1743,24 +1744,24 @@ func TestFIDO2Register_errors(t *testing.T) {
f2.setCallbacks()
const origin = "https://example.com"
- okCC := &wanlib.CredentialCreation{
- Response: protocol.PublicKeyCredentialCreationOptions{
+ okCC := &wantypes.CredentialCreation{
+ Response: wantypes.PublicKeyCredentialCreationOptions{
Challenge: make([]byte, 32),
- RelyingParty: protocol.RelyingPartyEntity{
+ RelyingParty: wantypes.RelyingPartyEntity{
ID: "example.com",
- CredentialEntity: protocol.CredentialEntity{
+ CredentialEntity: wantypes.CredentialEntity{
Name: "rp name",
},
},
- Parameters: []protocol.CredentialParameter{
+ Parameters: []wantypes.CredentialParameter{
{Type: protocol.PublicKeyCredentialType, Algorithm: webauthncose.AlgES256},
},
- AuthenticatorSelection: protocol.AuthenticatorSelection{
+ AuthenticatorSelection: wantypes.AuthenticatorSelection{
UserVerification: protocol.VerificationDiscouraged,
},
- User: protocol.UserEntity{
+ User: wantypes.UserEntity{
ID: []byte{1, 2, 3, 4, 1}, // arbitrary,
- CredentialEntity: protocol.CredentialEntity{
+ CredentialEntity: wantypes.CredentialEntity{
Name: "user name",
},
DisplayName: "user display name",
@@ -1771,8 +1772,8 @@ func TestFIDO2Register_errors(t *testing.T) {
pwdlessOK := *okCC
pwdlessOK.Response.RelyingParty.Name = "Teleport"
- pwdlessOK.Response.User = protocol.UserEntity{
- CredentialEntity: protocol.CredentialEntity{
+ pwdlessOK.Response.User = wantypes.UserEntity{
+ CredentialEntity: wantypes.CredentialEntity{
Name: "llama",
},
DisplayName: "Llama",
@@ -1787,27 +1788,27 @@ func TestFIDO2Register_errors(t *testing.T) {
tests := []struct {
name string
origin string
- createCC func() *wanlib.CredentialCreation
+ createCC func() *wantypes.CredentialCreation
prompt wancli.RegisterPrompt
wantErr string
}{
{
name: "ok - timeout", // check that good params are good
origin: origin,
- createCC: func() *wanlib.CredentialCreation { return okCC },
+ createCC: func() *wantypes.CredentialCreation { return okCC },
prompt: prompt,
wantErr: context.DeadlineExceeded.Error(),
},
{
name: "nil origin",
- createCC: func() *wanlib.CredentialCreation { return okCC },
+ createCC: func() *wantypes.CredentialCreation { return okCC },
prompt: prompt,
wantErr: "origin",
},
{
name: "cc without challenge",
origin: origin,
- createCC: func() *wanlib.CredentialCreation {
+ createCC: func() *wantypes.CredentialCreation {
cp := *okCC
cp.Response.Challenge = nil
return &cp
@@ -1818,9 +1819,9 @@ func TestFIDO2Register_errors(t *testing.T) {
{
name: "cc unsupported parameters",
origin: origin,
- createCC: func() *wanlib.CredentialCreation {
+ createCC: func() *wantypes.CredentialCreation {
cp := *okCC
- cp.Response.Parameters = []protocol.CredentialParameter{
+ cp.Response.Parameters = []wantypes.CredentialParameter{
{Type: protocol.PublicKeyCredentialType, Algorithm: webauthncose.AlgEdDSA},
}
return &cp
@@ -1831,7 +1832,7 @@ func TestFIDO2Register_errors(t *testing.T) {
{
name: "nil pinPrompt",
origin: origin,
- createCC: func() *wanlib.CredentialCreation { return okCC },
+ createCC: func() *wantypes.CredentialCreation { return okCC },
wantErr: "prompt",
},
}
@@ -1862,22 +1863,22 @@ func TestFIDO2Register_u2fExcludedCredentials(t *testing.T) {
f2.setCallbacks()
const origin = "https://example.com"
- cc := &wanlib.CredentialCreation{
- Response: protocol.PublicKeyCredentialCreationOptions{
+ cc := &wantypes.CredentialCreation{
+ Response: wantypes.PublicKeyCredentialCreationOptions{
Challenge: make([]byte, 32),
- RelyingParty: protocol.RelyingPartyEntity{
+ RelyingParty: wantypes.RelyingPartyEntity{
ID: "example.com",
- CredentialEntity: protocol.CredentialEntity{
+ CredentialEntity: wantypes.CredentialEntity{
Name: "rp name",
},
},
- Parameters: []protocol.CredentialParameter{
+ Parameters: []wantypes.CredentialParameter{
{Type: protocol.PublicKeyCredentialType, Algorithm: webauthncose.AlgES256},
},
- AuthenticatorSelection: protocol.AuthenticatorSelection{
+ AuthenticatorSelection: wantypes.AuthenticatorSelection{
UserVerification: protocol.VerificationDiscouraged,
},
- User: protocol.UserEntity{
+ User: wantypes.UserEntity{
ID: []byte{1, 2, 3, 4, 1}, // arbitrary,
CredentialEntity: protocol.CredentialEntity{
Name: "user name",
@@ -1895,7 +1896,7 @@ func TestFIDO2Register_u2fExcludedCredentials(t *testing.T) {
require.NoError(t, err, "FIDO2Register errored")
// Setup: mark the registered credential as excluded.
- cc.Response.CredentialExcludeList = append(cc.Response.CredentialExcludeList, protocol.CredentialDescriptor{
+ cc.Response.CredentialExcludeList = append(cc.Response.CredentialExcludeList, wantypes.CredentialDescriptor{
Type: protocol.PublicKeyCredentialType,
CredentialID: resp.GetWebauthn().GetRawId(),
})
diff --git a/lib/auth/webauthncli/u2f_login.go b/lib/auth/webauthncli/u2f_login.go
index 50f875243902c..5c563c746117a 100644
--- a/lib/auth/webauthncli/u2f_login.go
+++ b/lib/auth/webauthncli/u2f_login.go
@@ -27,13 +27,13 @@ import (
"github.com/gravitational/trace"
"github.com/gravitational/teleport/api/client/proto"
- wanlib "github.com/gravitational/teleport/lib/auth/webauthn"
+ wantypes "github.com/gravitational/teleport/lib/auth/webauthntypes"
)
// U2FLogin implements Login for U2F/CTAP1 devices.
// The implementation is backed exclusively by Go code, making it useful in
// scenarios where libfido2 is unavailable.
-func U2FLogin(ctx context.Context, origin string, assertion *wanlib.CredentialAssertion) (*proto.MFAAuthenticateResponse, error) {
+func U2FLogin(ctx context.Context, origin string, assertion *wantypes.CredentialAssertion) (*proto.MFAAuthenticateResponse, error) {
switch {
case origin == "":
return nil, trace.BadParameter("origin required")
@@ -72,16 +72,16 @@ func U2FLogin(ctx context.Context, origin string, assertion *wanlib.CredentialAs
// Did we get the App ID extension?
var appID string
var appIDHash [32]byte
- if value, ok := assertion.Response.Extensions[wanlib.AppIDExtension]; ok {
+ if value, ok := assertion.Response.Extensions[wantypes.AppIDExtension]; ok {
appID = fmt.Sprint(value)
appIDHash = sha256.Sum256([]byte(appID))
}
// Variables below are filled by the callback on success.
- var authCred protocol.CredentialDescriptor
+ var authCred wantypes.CredentialDescriptor
var authResp *u2ftoken.AuthenticateResponse
var usedAppID bool
- makeAuthU2F := func(cred protocol.CredentialDescriptor, req u2ftoken.AuthenticateRequest, appID bool) func(Token) error {
+ makeAuthU2F := func(cred wantypes.CredentialDescriptor, req u2ftoken.AuthenticateRequest, appID bool) func(Token) error {
return func(token Token) error {
if err := token.CheckAuthenticate(req); err != nil {
return err // don't wrap, inspected by RunOnU2FDevices
@@ -118,9 +118,9 @@ func U2FLogin(ctx context.Context, origin string, assertion *wanlib.CredentialAs
}
// Assemble extensions.
- var exts *wanlib.AuthenticationExtensionsClientOutputs
+ var exts *wantypes.AuthenticationExtensionsClientOutputs
if usedAppID {
- exts = &wanlib.AuthenticationExtensionsClientOutputs{AppID: true}
+ exts = &wantypes.AuthenticationExtensionsClientOutputs{AppID: true}
}
// Assemble authenticator data.
@@ -133,17 +133,17 @@ func U2FLogin(ctx context.Context, origin string, assertion *wanlib.CredentialAs
}
authData.Write(authResp.RawResponse[:5]) // User Presence (1) + Counter (4)
- resp := &wanlib.CredentialAssertionResponse{
- PublicKeyCredential: wanlib.PublicKeyCredential{
- Credential: wanlib.Credential{
+ resp := &wantypes.CredentialAssertionResponse{
+ PublicKeyCredential: wantypes.PublicKeyCredential{
+ Credential: wantypes.Credential{
ID: base64.RawURLEncoding.EncodeToString(authCred.CredentialID),
Type: string(protocol.PublicKeyCredentialType),
},
RawID: authCred.CredentialID,
Extensions: exts,
},
- AssertionResponse: wanlib.AuthenticatorAssertionResponse{
- AuthenticatorResponse: wanlib.AuthenticatorResponse{
+ AssertionResponse: wantypes.AuthenticatorAssertionResponse{
+ AuthenticatorResponse: wantypes.AuthenticatorResponse{
ClientDataJSON: ccdJSON,
},
AuthenticatorData: authData.Bytes(),
@@ -152,7 +152,7 @@ func U2FLogin(ctx context.Context, origin string, assertion *wanlib.CredentialAs
}
return &proto.MFAAuthenticateResponse{
Response: &proto.MFAAuthenticateResponse_Webauthn{
- Webauthn: wanlib.CredentialAssertionResponseToProto(resp),
+ Webauthn: wantypes.CredentialAssertionResponseToProto(resp),
},
}, nil
}
diff --git a/lib/auth/webauthncli/u2f_login_test.go b/lib/auth/webauthncli/u2f_login_test.go
index 9547dc7871345..6b63c07fec4d6 100644
--- a/lib/auth/webauthncli/u2f_login_test.go
+++ b/lib/auth/webauthncli/u2f_login_test.go
@@ -33,10 +33,11 @@ import (
"github.com/stretchr/testify/require"
"github.com/gravitational/teleport/api/types"
- wantypes "github.com/gravitational/teleport/api/types/webauthn"
+ wanpb "github.com/gravitational/teleport/api/types/webauthn"
"github.com/gravitational/teleport/lib/auth/mocku2f"
wanlib "github.com/gravitational/teleport/lib/auth/webauthn"
wancli "github.com/gravitational/teleport/lib/auth/webauthncli"
+ wantypes "github.com/gravitational/teleport/lib/auth/webauthntypes"
)
func TestLogin(t *testing.T) {
@@ -155,7 +156,7 @@ func TestLogin(t *testing.T) {
require.NotNil(t, mfaResp.GetWebauthn())
require.Equal(t, test.wantRawID, mfaResp.GetWebauthn().RawId)
- _, err = loginFlow.Finish(ctx, username, wanlib.CredentialAssertionResponseFromProto(mfaResp.GetWebauthn()))
+ _, err = loginFlow.Finish(ctx, username, wantypes.CredentialAssertionResponseFromProto(mfaResp.GetWebauthn()))
require.NoError(t, err)
})
}
@@ -184,33 +185,33 @@ func TestLogin_errors(t *testing.T) {
tests := []struct {
name string
origin string
- getAssertion func() *wanlib.CredentialAssertion
+ getAssertion func() *wantypes.CredentialAssertion
}{
{
name: "NOK origin empty",
origin: "",
- getAssertion: func() *wanlib.CredentialAssertion {
+ getAssertion: func() *wantypes.CredentialAssertion {
return okAssertion
},
},
{
name: "NOK assertion nil",
origin: origin,
- getAssertion: func() *wanlib.CredentialAssertion {
+ getAssertion: func() *wantypes.CredentialAssertion {
return nil
},
},
{
name: "NOK assertion empty",
origin: origin,
- getAssertion: func() *wanlib.CredentialAssertion {
- return &wanlib.CredentialAssertion{}
+ getAssertion: func() *wantypes.CredentialAssertion {
+ return &wantypes.CredentialAssertion{}
},
},
{
name: "NOK assertion missing challenge",
origin: origin,
- getAssertion: func() *wanlib.CredentialAssertion {
+ getAssertion: func() *wantypes.CredentialAssertion {
assertion, err := loginFlow.Begin(ctx, user)
require.NoError(t, err)
assertion.Response.Challenge = nil
@@ -220,7 +221,7 @@ func TestLogin_errors(t *testing.T) {
{
name: "NOK assertion missing RPID",
origin: origin,
- getAssertion: func() *wanlib.CredentialAssertion {
+ getAssertion: func() *wantypes.CredentialAssertion {
assertion, err := loginFlow.Begin(ctx, user)
require.NoError(t, err)
assertion.Response.RelyingPartyID = ""
@@ -230,7 +231,7 @@ func TestLogin_errors(t *testing.T) {
{
name: "NOK assertion missing credentials",
origin: origin,
- getAssertion: func() *wanlib.CredentialAssertion {
+ getAssertion: func() *wantypes.CredentialAssertion {
assertion, err := loginFlow.Begin(ctx, user)
require.NoError(t, err)
assertion.Response.AllowedCredentials = nil
@@ -240,7 +241,7 @@ func TestLogin_errors(t *testing.T) {
{
name: "NOK assertion invalid user verification requirement",
origin: origin,
- getAssertion: func() *wanlib.CredentialAssertion {
+ getAssertion: func() *wantypes.CredentialAssertion {
assertion, err := loginFlow.Begin(ctx, user)
require.NoError(t, err)
assertion.Response.UserVerification = protocol.VerificationRequired
@@ -421,7 +422,7 @@ type fakeIdentity struct {
User string
Devices []*types.MFADevice
LocalAuth *types.WebauthnLocalAuth
- SessionData *wantypes.SessionData
+ SessionData *wanpb.SessionData
}
func (f *fakeIdentity) UpsertWebauthnLocalAuth(ctx context.Context, user string, wla *types.WebauthnLocalAuth) error {
@@ -452,12 +453,12 @@ func (f *fakeIdentity) UpsertMFADevice(ctx context.Context, user string, d *type
return nil
}
-func (f *fakeIdentity) UpsertWebauthnSessionData(ctx context.Context, user, sessionID string, sd *wantypes.SessionData) error {
+func (f *fakeIdentity) UpsertWebauthnSessionData(ctx context.Context, user, sessionID string, sd *wanpb.SessionData) error {
f.SessionData = sd
return nil
}
-func (f *fakeIdentity) GetWebauthnSessionData(ctx context.Context, user, sessionID string) (*wantypes.SessionData, error) {
+func (f *fakeIdentity) GetWebauthnSessionData(ctx context.Context, user, sessionID string) (*wanpb.SessionData, error) {
return f.SessionData, nil
}
diff --git a/lib/auth/webauthncli/u2f_register.go b/lib/auth/webauthncli/u2f_register.go
index 9ff84d0972d2e..04bc02cef15a9 100644
--- a/lib/auth/webauthncli/u2f_register.go
+++ b/lib/auth/webauthncli/u2f_register.go
@@ -36,12 +36,13 @@ import (
"github.com/gravitational/teleport/api/client/proto"
wanlib "github.com/gravitational/teleport/lib/auth/webauthn"
+ wantypes "github.com/gravitational/teleport/lib/auth/webauthntypes"
)
// U2FRegister implements Register for U2F/CTAP1 devices.
// The implementation is backed exclusively by Go code, making it useful in
// scenarios where libfido2 is unavailable.
-func U2FRegister(ctx context.Context, origin string, cc *wanlib.CredentialCreation) (*proto.MFARegisterResponse, error) {
+func U2FRegister(ctx context.Context, origin string, cc *wantypes.CredentialCreation) (*proto.MFARegisterResponse, error) {
// Preliminary checks, more below.
switch {
case origin == "":
@@ -88,7 +89,7 @@ func U2FRegister(ctx context.Context, origin string, cc *wanlib.CredentialCreati
rpIDHash := sha256.Sum256([]byte(cc.Response.RelyingParty.ID))
var appIDHash []byte
- if value, ok := cc.Response.Extensions[wanlib.AppIDExtension]; ok {
+ if value, ok := cc.Response.Extensions[wantypes.AppIDExtension]; ok {
appID := fmt.Sprint(value)
h := sha256.Sum256([]byte(appID))
appIDHash = h[:]
@@ -144,7 +145,7 @@ func U2FRegister(ctx context.Context, origin string, cc *wanlib.CredentialCreati
return &proto.MFARegisterResponse{
Response: &proto.MFARegisterResponse_Webauthn{
- Webauthn: wanlib.CredentialCreationResponseToProto(ccr),
+ Webauthn: wantypes.CredentialCreationResponseToProto(ccr),
},
}, nil
}
@@ -223,7 +224,7 @@ func parseU2FRegistrationResponse(resp []byte) (*u2fRegistrationResponse, error)
}, nil
}
-func credentialResponseFromU2F(ccdJSON, appIDHash []byte, resp *u2fRegistrationResponse) (*wanlib.CredentialCreationResponse, error) {
+func credentialResponseFromU2F(ccdJSON, appIDHash []byte, resp *u2fRegistrationResponse) (*wantypes.CredentialCreationResponse, error) {
// Reference:
// https://fidoalliance.org/specs/fido-v2.1-ps-20210615/fido-client-to-authenticator-protocol-v2.1-ps-20210615.html#fig-u2f-compat-makeCredential
@@ -258,16 +259,16 @@ func credentialResponseFromU2F(ccdJSON, appIDHash []byte, resp *u2fRegistrationR
return nil, trace.Wrap(err)
}
- return &wanlib.CredentialCreationResponse{
- PublicKeyCredential: wanlib.PublicKeyCredential{
- Credential: wanlib.Credential{
+ return &wantypes.CredentialCreationResponse{
+ PublicKeyCredential: wantypes.PublicKeyCredential{
+ Credential: wantypes.Credential{
ID: base64.RawURLEncoding.EncodeToString(resp.KeyHandle),
Type: string(protocol.PublicKeyCredentialType),
},
RawID: resp.KeyHandle,
},
- AttestationResponse: wanlib.AuthenticatorAttestationResponse{
- AuthenticatorResponse: wanlib.AuthenticatorResponse{
+ AttestationResponse: wantypes.AuthenticatorAttestationResponse{
+ AuthenticatorResponse: wantypes.AuthenticatorResponse{
ClientDataJSON: ccdJSON,
},
AttestationObject: attestationObj,
diff --git a/lib/auth/webauthncli/u2f_register_test.go b/lib/auth/webauthncli/u2f_register_test.go
index 5ff4ae7831c7f..27492909cff6f 100644
--- a/lib/auth/webauthncli/u2f_register_test.go
+++ b/lib/auth/webauthncli/u2f_register_test.go
@@ -26,6 +26,7 @@ import (
"github.com/gravitational/teleport/api/types"
wanlib "github.com/gravitational/teleport/lib/auth/webauthn"
wancli "github.com/gravitational/teleport/lib/auth/webauthncli"
+ wantypes "github.com/gravitational/teleport/lib/auth/webauthntypes"
)
func TestRegister(t *testing.T) {
@@ -113,7 +114,7 @@ func TestRegister(t *testing.T) {
_, err = webRegistration.Finish(ctx, wanlib.RegisterResponse{
User: user,
DeviceName: u2fKey.name,
- CreationResponse: wanlib.CredentialCreationResponseFromProto(resp.GetWebauthn()),
+ CreationResponse: wantypes.CredentialCreationResponseFromProto(resp.GetWebauthn()),
})
require.NoError(t, err, "server-side registration failed")
})
@@ -136,33 +137,33 @@ func TestRegister_errors(t *testing.T) {
tests := []struct {
name string
origin string
- makeCC func() *wanlib.CredentialCreation
+ makeCC func() *wantypes.CredentialCreation
wantErr string
}{
{
name: "NOK empty origin",
origin: "",
- makeCC: func() *wanlib.CredentialCreation { return okCC },
+ makeCC: func() *wantypes.CredentialCreation { return okCC },
wantErr: "origin",
},
{
name: "NOK nil credential creation",
origin: origin,
- makeCC: func() *wanlib.CredentialCreation { return nil },
+ makeCC: func() *wantypes.CredentialCreation { return nil },
wantErr: "credential creation required",
},
{
name: "NOK nil empty creation",
origin: origin,
- makeCC: func() *wanlib.CredentialCreation { return &wanlib.CredentialCreation{} },
+ makeCC: func() *wantypes.CredentialCreation { return &wantypes.CredentialCreation{} },
wantErr: "relying party",
},
{
name: "NOK ES256 algorithm not allowed",
origin: origin,
- makeCC: func() *wanlib.CredentialCreation {
+ makeCC: func() *wantypes.CredentialCreation {
cp := *okCC
- var params []protocol.CredentialParameter
+ var params []wantypes.CredentialParameter
for _, p := range cp.Response.Parameters {
if p.Algorithm == webauthncose.AlgES256 {
continue
@@ -177,7 +178,7 @@ func TestRegister_errors(t *testing.T) {
{
name: "NOK platform attachment required",
origin: origin,
- makeCC: func() *wanlib.CredentialCreation {
+ makeCC: func() *wantypes.CredentialCreation {
cp := *okCC
cp.Response.AuthenticatorSelection.AuthenticatorAttachment = protocol.Platform
return &cp
@@ -187,7 +188,7 @@ func TestRegister_errors(t *testing.T) {
{
name: "NOK resident key required",
origin: origin,
- makeCC: func() *wanlib.CredentialCreation {
+ makeCC: func() *wantypes.CredentialCreation {
cp := *okCC
rrk := true
cp.Response.AuthenticatorSelection.RequireResidentKey = &rrk
@@ -198,7 +199,7 @@ func TestRegister_errors(t *testing.T) {
{
name: "NOK user verification required",
origin: origin,
- makeCC: func() *wanlib.CredentialCreation {
+ makeCC: func() *wantypes.CredentialCreation {
cp := *okCC
cp.Response.AuthenticatorSelection.UserVerification = protocol.VerificationRequired
return &cp
diff --git a/lib/auth/webauthntypes/doc.go b/lib/auth/webauthntypes/doc.go
new file mode 100644
index 0000000000000..fafae46e496b4
--- /dev/null
+++ b/lib/auth/webauthntypes/doc.go
@@ -0,0 +1,20 @@
+// Copyright 2023 Gravitational, Inc
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Package webauthntypes provides WebAuthn types and conversions for both
+// client-side and server-side implementations.
+//
+// Many of the types found in the package are replicas of go-webauthn/webauthn
+// types, "frozen" as to avoid changes in their JSON representation.
+package webauthntypes
diff --git a/lib/auth/webauthntypes/extensions.go b/lib/auth/webauthntypes/extensions.go
new file mode 100644
index 0000000000000..adc2b7a4621f5
--- /dev/null
+++ b/lib/auth/webauthntypes/extensions.go
@@ -0,0 +1,19 @@
+// Copyright 2021 Gravitational, Inc
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package webauthntypes
+
+// AppIDExtension is the key for the appid extension.
+// https://www.w3.org/TR/webauthn-2/#sctn-appid-extension.
+const AppIDExtension = "appid"
diff --git a/lib/auth/webauthn/proto.go b/lib/auth/webauthntypes/proto.go
similarity index 65%
rename from lib/auth/webauthn/proto.go
rename to lib/auth/webauthntypes/proto.go
index 87baa00ade00d..938896e8cf1f8 100644
--- a/lib/auth/webauthn/proto.go
+++ b/lib/auth/webauthntypes/proto.go
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package webauthn
+package webauthntypes
import (
"encoding/base64"
@@ -20,17 +20,17 @@ import (
"github.com/go-webauthn/webauthn/protocol"
"github.com/go-webauthn/webauthn/protocol/webauthncose"
- wantypes "github.com/gravitational/teleport/api/types/webauthn"
+ wanpb "github.com/gravitational/teleport/api/types/webauthn"
)
// CredentialAssertionToProto converts a CredentialAssertion to its proto
// counterpart.
-func CredentialAssertionToProto(assertion *CredentialAssertion) *wantypes.CredentialAssertion {
+func CredentialAssertionToProto(assertion *CredentialAssertion) *wanpb.CredentialAssertion {
if assertion == nil {
return nil
}
- return &wantypes.CredentialAssertion{
- PublicKey: &wantypes.PublicKeyCredentialRequestOptions{
+ return &wanpb.CredentialAssertion{
+ PublicKey: &wanpb.PublicKeyCredentialRequestOptions{
Challenge: assertion.Response.Challenge,
TimeoutMs: int64(assertion.Response.Timeout),
RpId: assertion.Response.RelyingPartyID,
@@ -43,14 +43,14 @@ func CredentialAssertionToProto(assertion *CredentialAssertion) *wantypes.Creden
// CredentialAssertionResponseToProto converts a CredentialAssertionResponse to
// its proto counterpart.
-func CredentialAssertionResponseToProto(car *CredentialAssertionResponse) *wantypes.CredentialAssertionResponse {
+func CredentialAssertionResponseToProto(car *CredentialAssertionResponse) *wanpb.CredentialAssertionResponse {
if car == nil {
return nil
}
- return &wantypes.CredentialAssertionResponse{
+ return &wanpb.CredentialAssertionResponse{
Type: car.Type,
RawId: car.RawID,
- Response: &wantypes.AuthenticatorAssertionResponse{
+ Response: &wanpb.AuthenticatorAssertionResponse{
ClientDataJson: car.AssertionResponse.ClientDataJSON,
AuthenticatorData: car.AssertionResponse.AuthenticatorData,
Signature: car.AssertionResponse.Signature,
@@ -62,12 +62,12 @@ func CredentialAssertionResponseToProto(car *CredentialAssertionResponse) *wanty
// CredentialCreationToProto converts a CredentialCreation to its proto
// counterpart.
-func CredentialCreationToProto(cc *CredentialCreation) *wantypes.CredentialCreation {
+func CredentialCreationToProto(cc *CredentialCreation) *wanpb.CredentialCreation {
if cc == nil {
return nil
}
- return &wantypes.CredentialCreation{
- PublicKey: &wantypes.PublicKeyCredentialCreationOptions{
+ return &wanpb.CredentialCreation{
+ PublicKey: &wanpb.PublicKeyCredentialCreationOptions{
Challenge: cc.Response.Challenge,
Rp: rpEntityToProto(cc.Response.RelyingParty),
User: userEntityToProto(cc.Response.User),
@@ -83,14 +83,14 @@ func CredentialCreationToProto(cc *CredentialCreation) *wantypes.CredentialCreat
// CredentialCreationResponseToProto converts a CredentialCreationResponse to
// its proto counterpart.
-func CredentialCreationResponseToProto(ccr *CredentialCreationResponse) *wantypes.CredentialCreationResponse {
+func CredentialCreationResponseToProto(ccr *CredentialCreationResponse) *wanpb.CredentialCreationResponse {
if ccr == nil {
return nil
}
- return &wantypes.CredentialCreationResponse{
+ return &wanpb.CredentialCreationResponse{
Type: ccr.Type,
RawId: ccr.RawID,
- Response: &wantypes.AuthenticatorAttestationResponse{
+ Response: &wanpb.AuthenticatorAttestationResponse{
ClientDataJson: ccr.AttestationResponse.ClientDataJSON,
AttestationObject: ccr.AttestationResponse.AttestationObject,
},
@@ -100,7 +100,7 @@ func CredentialCreationResponseToProto(ccr *CredentialCreationResponse) *wantype
// CredentialAssertionFromProto converts a CredentialAssertion proto to its lib
// counterpart.
-func CredentialAssertionFromProto(assertion *wantypes.CredentialAssertion) *CredentialAssertion {
+func CredentialAssertionFromProto(assertion *wanpb.CredentialAssertion) *CredentialAssertion {
if assertion == nil {
return nil
}
@@ -111,7 +111,7 @@ func CredentialAssertionFromProto(assertion *wantypes.CredentialAssertion) *Cred
// CredentialAssertionResponseFromProto converts a CredentialAssertionResponse
// proto to its lib counterpart.
-func CredentialAssertionResponseFromProto(car *wantypes.CredentialAssertionResponse) *CredentialAssertionResponse {
+func CredentialAssertionResponseFromProto(car *wanpb.CredentialAssertionResponse) *CredentialAssertionResponse {
if car == nil {
return nil
}
@@ -130,7 +130,7 @@ func CredentialAssertionResponseFromProto(car *wantypes.CredentialAssertionRespo
// CredentialCreationFromProto converts a CredentialCreation proto to its lib
// counterpart.
-func CredentialCreationFromProto(cc *wantypes.CredentialCreation) *CredentialCreation {
+func CredentialCreationFromProto(cc *wanpb.CredentialCreation) *CredentialCreation {
if cc == nil {
return nil
}
@@ -141,7 +141,7 @@ func CredentialCreationFromProto(cc *wantypes.CredentialCreation) *CredentialCre
// CredentialCreationResponseFromProto converts a CredentialCreationResponse
// proto to its lib counterpart.
-func CredentialCreationResponseFromProto(ccr *wantypes.CredentialCreationResponse) *CredentialCreationResponse {
+func CredentialCreationResponseFromProto(ccr *wanpb.CredentialCreationResponse) *CredentialCreationResponse {
if ccr == nil {
return nil
}
@@ -158,18 +158,18 @@ func CredentialCreationResponseFromProto(ccr *wantypes.CredentialCreationRespons
}
}
-func authenticatorSelectionToProto(a protocol.AuthenticatorSelection) *wantypes.AuthenticatorSelection {
- return &wantypes.AuthenticatorSelection{
+func authenticatorSelectionToProto(a AuthenticatorSelection) *wanpb.AuthenticatorSelection {
+ return &wanpb.AuthenticatorSelection{
AuthenticatorAttachment: string(a.AuthenticatorAttachment),
RequireResidentKey: a.RequireResidentKey != nil && *a.RequireResidentKey,
UserVerification: string(a.UserVerification),
}
}
-func credentialDescriptorsToProto(creds []protocol.CredentialDescriptor) []*wantypes.CredentialDescriptor {
- res := make([]*wantypes.CredentialDescriptor, len(creds))
+func credentialDescriptorsToProto(creds []CredentialDescriptor) []*wanpb.CredentialDescriptor {
+ res := make([]*wanpb.CredentialDescriptor, len(creds))
for i, cred := range creds {
- res[i] = &wantypes.CredentialDescriptor{
+ res[i] = &wanpb.CredentialDescriptor{
Type: string(cred.Type),
Id: cred.CredentialID,
}
@@ -177,10 +177,10 @@ func credentialDescriptorsToProto(creds []protocol.CredentialDescriptor) []*want
return res
}
-func credentialParametersToProto(params []protocol.CredentialParameter) []*wantypes.CredentialParameter {
- res := make([]*wantypes.CredentialParameter, len(params))
+func credentialParametersToProto(params []CredentialParameter) []*wanpb.CredentialParameter {
+ res := make([]*wanpb.CredentialParameter, len(params))
for i, p := range params {
- res[i] = &wantypes.CredentialParameter{
+ res[i] = &wanpb.CredentialParameter{
Type: string(p.Type),
Alg: int32(p.Algorithm),
}
@@ -188,11 +188,11 @@ func credentialParametersToProto(params []protocol.CredentialParameter) []*wanty
return res
}
-func inputExtensionsToProto(exts protocol.AuthenticationExtensions) *wantypes.AuthenticationExtensionsClientInputs {
+func inputExtensionsToProto(exts AuthenticationExtensions) *wanpb.AuthenticationExtensionsClientInputs {
if len(exts) == 0 {
return nil
}
- res := &wantypes.AuthenticationExtensionsClientInputs{}
+ res := &wanpb.AuthenticationExtensionsClientInputs{}
if value, ok := exts[AppIDExtension]; ok {
// Type should always be string, since we are the ones setting it, but let's
// play it safe and check anyway.
@@ -203,33 +203,31 @@ func inputExtensionsToProto(exts protocol.AuthenticationExtensions) *wantypes.Au
return res
}
-func outputExtensionsToProto(exts *AuthenticationExtensionsClientOutputs) *wantypes.AuthenticationExtensionsClientOutputs {
+func outputExtensionsToProto(exts *AuthenticationExtensionsClientOutputs) *wanpb.AuthenticationExtensionsClientOutputs {
if exts == nil {
return nil
}
- return &wantypes.AuthenticationExtensionsClientOutputs{
+ return &wanpb.AuthenticationExtensionsClientOutputs{
AppId: exts.AppID,
}
}
-func rpEntityToProto(rp protocol.RelyingPartyEntity) *wantypes.RelyingPartyEntity {
- return &wantypes.RelyingPartyEntity{
+func rpEntityToProto(rp RelyingPartyEntity) *wanpb.RelyingPartyEntity {
+ return &wanpb.RelyingPartyEntity{
Id: rp.ID,
Name: rp.Name,
- Icon: rp.Icon,
}
}
-func userEntityToProto(user protocol.UserEntity) *wantypes.UserEntity {
- return &wantypes.UserEntity{
+func userEntityToProto(user UserEntity) *wanpb.UserEntity {
+ return &wanpb.UserEntity{
Id: user.ID,
Name: user.Name,
DisplayName: user.DisplayName,
- Icon: user.Icon,
}
}
-func authenticatorAssertionResponseFromProto(resp *wantypes.AuthenticatorAssertionResponse) AuthenticatorAssertionResponse {
+func authenticatorAssertionResponseFromProto(resp *wanpb.AuthenticatorAssertionResponse) AuthenticatorAssertionResponse {
if resp == nil {
return AuthenticatorAssertionResponse{}
}
@@ -243,7 +241,7 @@ func authenticatorAssertionResponseFromProto(resp *wantypes.AuthenticatorAsserti
}
}
-func authenticatorAttestationResponseFromProto(resp *wantypes.AuthenticatorAttestationResponse) AuthenticatorAttestationResponse {
+func authenticatorAttestationResponseFromProto(resp *wanpb.AuthenticatorAttestationResponse) AuthenticatorAttestationResponse {
if resp == nil {
return AuthenticatorAttestationResponse{}
}
@@ -255,25 +253,25 @@ func authenticatorAttestationResponseFromProto(resp *wantypes.AuthenticatorAttes
}
}
-func authenticatorSelectionFromProto(a *wantypes.AuthenticatorSelection) protocol.AuthenticatorSelection {
+func authenticatorSelectionFromProto(a *wanpb.AuthenticatorSelection) AuthenticatorSelection {
if a == nil {
- return protocol.AuthenticatorSelection{}
+ return AuthenticatorSelection{}
}
rrk := a.RequireResidentKey
- return protocol.AuthenticatorSelection{
+ return AuthenticatorSelection{
AuthenticatorAttachment: protocol.AuthenticatorAttachment(a.AuthenticatorAttachment),
RequireResidentKey: &rrk,
UserVerification: protocol.UserVerificationRequirement(a.UserVerification),
}
}
-func credentialDescriptorsFromProto(creds []*wantypes.CredentialDescriptor) []protocol.CredentialDescriptor {
- var res []protocol.CredentialDescriptor
+func credentialDescriptorsFromProto(creds []*wanpb.CredentialDescriptor) []CredentialDescriptor {
+ var res []CredentialDescriptor
for _, cred := range creds {
if cred == nil {
continue
}
- res = append(res, protocol.CredentialDescriptor{
+ res = append(res, CredentialDescriptor{
Type: protocol.CredentialType(cred.Type),
CredentialID: cred.Id,
})
@@ -281,13 +279,13 @@ func credentialDescriptorsFromProto(creds []*wantypes.CredentialDescriptor) []pr
return res
}
-func credentialParametersFromProto(params []*wantypes.CredentialParameter) []protocol.CredentialParameter {
- var res []protocol.CredentialParameter
+func credentialParametersFromProto(params []*wanpb.CredentialParameter) []CredentialParameter {
+ var res []CredentialParameter
for _, p := range params {
if p == nil {
continue
}
- res = append(res, protocol.CredentialParameter{
+ res = append(res, CredentialParameter{
Type: protocol.CredentialType(p.Type),
Algorithm: webauthncose.COSEAlgorithmIdentifier(p.Alg),
})
@@ -295,7 +293,7 @@ func credentialParametersFromProto(params []*wantypes.CredentialParameter) []pro
return res
}
-func inputExtensionsFromProto(exts *wantypes.AuthenticationExtensionsClientInputs) protocol.AuthenticationExtensions {
+func inputExtensionsFromProto(exts *wanpb.AuthenticationExtensionsClientInputs) AuthenticationExtensions {
if exts == nil {
return nil
}
@@ -306,7 +304,7 @@ func inputExtensionsFromProto(exts *wantypes.AuthenticationExtensionsClientInput
return res
}
-func outputExtensionsFromProto(exts *wantypes.AuthenticationExtensionsClientOutputs) *AuthenticationExtensionsClientOutputs {
+func outputExtensionsFromProto(exts *wanpb.AuthenticationExtensionsClientOutputs) *AuthenticationExtensionsClientOutputs {
if exts == nil {
return nil
}
@@ -315,11 +313,11 @@ func outputExtensionsFromProto(exts *wantypes.AuthenticationExtensionsClientOutp
}
}
-func publicKeyCredentialCreationOptionsFromProto(pubKey *wantypes.PublicKeyCredentialCreationOptions) protocol.PublicKeyCredentialCreationOptions {
+func publicKeyCredentialCreationOptionsFromProto(pubKey *wanpb.PublicKeyCredentialCreationOptions) PublicKeyCredentialCreationOptions {
if pubKey == nil {
- return protocol.PublicKeyCredentialCreationOptions{}
+ return PublicKeyCredentialCreationOptions{}
}
- return protocol.PublicKeyCredentialCreationOptions{
+ return PublicKeyCredentialCreationOptions{
Challenge: pubKey.Challenge,
RelyingParty: rpEntityFromProto(pubKey.Rp),
User: userEntityFromProto(pubKey.User),
@@ -332,11 +330,11 @@ func publicKeyCredentialCreationOptionsFromProto(pubKey *wantypes.PublicKeyCrede
}
}
-func publicKeyCredentialRequestOptionsFromProto(pubKey *wantypes.PublicKeyCredentialRequestOptions) protocol.PublicKeyCredentialRequestOptions {
+func publicKeyCredentialRequestOptionsFromProto(pubKey *wanpb.PublicKeyCredentialRequestOptions) PublicKeyCredentialRequestOptions {
if pubKey == nil {
- return protocol.PublicKeyCredentialRequestOptions{}
+ return PublicKeyCredentialRequestOptions{}
}
- return protocol.PublicKeyCredentialRequestOptions{
+ return PublicKeyCredentialRequestOptions{
Challenge: pubKey.Challenge,
Timeout: int(pubKey.TimeoutMs),
RelyingPartyID: pubKey.RpId,
@@ -346,27 +344,25 @@ func publicKeyCredentialRequestOptionsFromProto(pubKey *wantypes.PublicKeyCreden
}
}
-func rpEntityFromProto(rp *wantypes.RelyingPartyEntity) protocol.RelyingPartyEntity {
+func rpEntityFromProto(rp *wanpb.RelyingPartyEntity) RelyingPartyEntity {
if rp == nil {
- return protocol.RelyingPartyEntity{}
+ return RelyingPartyEntity{}
}
- return protocol.RelyingPartyEntity{
- CredentialEntity: protocol.CredentialEntity{
+ return RelyingPartyEntity{
+ CredentialEntity: CredentialEntity{
Name: rp.Name,
- Icon: rp.Icon,
},
ID: rp.Id,
}
}
-func userEntityFromProto(user *wantypes.UserEntity) protocol.UserEntity {
+func userEntityFromProto(user *wanpb.UserEntity) UserEntity {
if user == nil {
- return protocol.UserEntity{}
+ return UserEntity{}
}
- return protocol.UserEntity{
- CredentialEntity: protocol.CredentialEntity{
+ return UserEntity{
+ CredentialEntity: CredentialEntity{
Name: user.Name,
- Icon: user.Icon,
},
DisplayName: user.DisplayName,
ID: user.Id,
diff --git a/lib/auth/webauthn/proto_test.go b/lib/auth/webauthntypes/proto_test.go
similarity index 59%
rename from lib/auth/webauthn/proto_test.go
rename to lib/auth/webauthntypes/proto_test.go
index ff1c60f1fbd78..66d82662bbccd 100644
--- a/lib/auth/webauthn/proto_test.go
+++ b/lib/auth/webauthntypes/proto_test.go
@@ -12,15 +12,15 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package webauthn_test
+package webauthntypes_test
import (
"testing"
"github.com/stretchr/testify/require"
- wantypes "github.com/gravitational/teleport/api/types/webauthn"
- wanlib "github.com/gravitational/teleport/lib/auth/webauthn"
+ wanpb "github.com/gravitational/teleport/api/types/webauthn"
+ wantypes "github.com/gravitational/teleport/lib/auth/webauthntypes"
)
func TestConversionFromProto_nils(t *testing.T) {
@@ -37,29 +37,29 @@ func TestConversionFromProto_nils(t *testing.T) {
{
name: "CredentialAssertion nil",
fn: func() {
- wanlib.CredentialAssertionFromProto(nil)
+ wantypes.CredentialAssertionFromProto(nil)
},
},
{
name: "CredentialAssertion empty",
fn: func() {
- wanlib.CredentialAssertionFromProto(&wantypes.CredentialAssertion{})
+ wantypes.CredentialAssertionFromProto(&wanpb.CredentialAssertion{})
},
},
{
name: "CredentialAssertion.PublicKey empty",
fn: func() {
- wanlib.CredentialAssertionFromProto(&wantypes.CredentialAssertion{
- PublicKey: &wantypes.PublicKeyCredentialRequestOptions{},
+ wantypes.CredentialAssertionFromProto(&wanpb.CredentialAssertion{
+ PublicKey: &wanpb.PublicKeyCredentialRequestOptions{},
})
},
},
{
name: "CredentialAssertion.PublicKey slice elements nil",
fn: func() {
- wanlib.CredentialAssertionFromProto(&wantypes.CredentialAssertion{
- PublicKey: &wantypes.PublicKeyCredentialRequestOptions{
- AllowCredentials: []*wantypes.CredentialDescriptor{
+ wantypes.CredentialAssertionFromProto(&wanpb.CredentialAssertion{
+ PublicKey: &wanpb.PublicKeyCredentialRequestOptions{
+ AllowCredentials: []*wanpb.CredentialDescriptor{
{}, nil, {},
},
},
@@ -69,52 +69,52 @@ func TestConversionFromProto_nils(t *testing.T) {
{
name: "CredentialAssertionResponse nil",
fn: func() {
- wanlib.CredentialAssertionResponseFromProto(nil)
+ wantypes.CredentialAssertionResponseFromProto(nil)
},
},
{
name: "CredentialAssertionResponse empty",
fn: func() {
- wanlib.CredentialAssertionResponseFromProto(&wantypes.CredentialAssertionResponse{})
+ wantypes.CredentialAssertionResponseFromProto(&wanpb.CredentialAssertionResponse{})
},
},
{
name: "CredentialAssertionResponse.Response empty",
fn: func() {
- wanlib.CredentialAssertionResponseFromProto(&wantypes.CredentialAssertionResponse{
- Response: &wantypes.AuthenticatorAssertionResponse{},
+ wantypes.CredentialAssertionResponseFromProto(&wanpb.CredentialAssertionResponse{
+ Response: &wanpb.AuthenticatorAssertionResponse{},
})
},
},
{
name: "CredentialCreation nil",
fn: func() {
- wanlib.CredentialCreationFromProto(nil)
+ wantypes.CredentialCreationFromProto(nil)
},
},
{
name: "CredentialCreation empty",
fn: func() {
- wanlib.CredentialCreationFromProto(&wantypes.CredentialCreation{})
+ wantypes.CredentialCreationFromProto(&wanpb.CredentialCreation{})
},
},
{
name: "CredentialCreation.PublicKey empty",
fn: func() {
- wanlib.CredentialCreationFromProto(&wantypes.CredentialCreation{
- PublicKey: &wantypes.PublicKeyCredentialCreationOptions{},
+ wantypes.CredentialCreationFromProto(&wanpb.CredentialCreation{
+ PublicKey: &wanpb.PublicKeyCredentialCreationOptions{},
})
},
},
{
name: "CredentialCreation.PublicKey slice elements nil",
fn: func() {
- wanlib.CredentialCreationFromProto(&wantypes.CredentialCreation{
- PublicKey: &wantypes.PublicKeyCredentialCreationOptions{
- CredentialParameters: []*wantypes.CredentialParameter{
+ wantypes.CredentialCreationFromProto(&wanpb.CredentialCreation{
+ PublicKey: &wanpb.PublicKeyCredentialCreationOptions{
+ CredentialParameters: []*wanpb.CredentialParameter{
{}, nil, {},
},
- ExcludeCredentials: []*wantypes.CredentialDescriptor{
+ ExcludeCredentials: []*wanpb.CredentialDescriptor{
{}, nil, {},
},
},
@@ -124,20 +124,20 @@ func TestConversionFromProto_nils(t *testing.T) {
{
name: "CredentialCreationResponse nil",
fn: func() {
- wanlib.CredentialCreationResponseFromProto(nil)
+ wantypes.CredentialCreationResponseFromProto(nil)
},
},
{
name: "CredentialCreationResponse empty",
fn: func() {
- wanlib.CredentialCreationResponseFromProto(&wantypes.CredentialCreationResponse{})
+ wantypes.CredentialCreationResponseFromProto(&wanpb.CredentialCreationResponse{})
},
},
{
name: "CredentialCreationResponse.Response empty",
fn: func() {
- wanlib.CredentialCreationResponseFromProto(&wantypes.CredentialCreationResponse{
- Response: &wantypes.AuthenticatorAttestationResponse{},
+ wantypes.CredentialCreationResponseFromProto(&wanpb.CredentialCreationResponse{
+ Response: &wanpb.AuthenticatorAttestationResponse{},
})
},
},
diff --git a/lib/auth/webauthntypes/webauthn.go b/lib/auth/webauthntypes/webauthn.go
new file mode 100644
index 0000000000000..01e636816326e
--- /dev/null
+++ b/lib/auth/webauthntypes/webauthn.go
@@ -0,0 +1,359 @@
+// Copyright 2021 Gravitational, Inc
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package webauthntypes
+
+import (
+ "encoding/base64"
+
+ "github.com/go-webauthn/webauthn/protocol"
+ "github.com/go-webauthn/webauthn/protocol/webauthncose"
+ "github.com/gravitational/trace"
+)
+
+// CredentialAssertion is the payload sent to authenticators to initiate login.
+type CredentialAssertion struct {
+ Response PublicKeyCredentialRequestOptions `json:"publicKey"`
+}
+
+// PublicKeyCredentialRequestOptions is a clone of
+// [protocol.PublicKeyCredentialRequestOptions], materialized here to keep a
+// stable JSON marshal/unmarshal representation.
+type PublicKeyCredentialRequestOptions struct {
+ Challenge Challenge `json:"challenge"`
+ Timeout int `json:"timeout,omitempty"`
+ RelyingPartyID string `json:"rpId,omitempty"`
+ AllowedCredentials []CredentialDescriptor `json:"allowCredentials,omitempty"`
+ UserVerification protocol.UserVerificationRequirement `json:"userVerification,omitempty"` // Default is "preferred"
+ Extensions AuthenticationExtensions `json:"extensions,omitempty"`
+}
+
+func (a *PublicKeyCredentialRequestOptions) GetAllowedCredentialIDs() [][]byte {
+ var allowedCredentialIDs = make([][]byte, len(a.AllowedCredentials))
+ for i, credential := range a.AllowedCredentials {
+ allowedCredentialIDs[i] = credential.CredentialID
+ }
+ return allowedCredentialIDs
+}
+
+// Validate performs client-side validation of CredentialAssertion.
+// It makes sure that data are valid and can be sent to authenticator.
+// This is general purpose validation and authenticator should add its own
+// on top of it, if necessary.
+func (ca *CredentialAssertion) Validate() error {
+ switch {
+ case ca == nil:
+ return trace.BadParameter("credential assertion required")
+ case len(ca.Response.Challenge) == 0:
+ return trace.BadParameter("credential assertion challenge required")
+ case ca.Response.RelyingPartyID == "":
+ return trace.BadParameter("credential assertion relying party ID required")
+ }
+ return nil
+}
+
+// CredentialAssertionFromProtocol converts a [protocol.CredentialAssertion] to
+// a [CredentialAssertion].
+func CredentialAssertionFromProtocol(a *protocol.CredentialAssertion) *CredentialAssertion {
+ if a == nil {
+ return nil
+ }
+
+ return &CredentialAssertion{
+ Response: PublicKeyCredentialRequestOptions{
+ Challenge: Challenge(a.Response.Challenge),
+ Timeout: a.Response.Timeout,
+ RelyingPartyID: a.Response.RelyingPartyID,
+ AllowedCredentials: credentialDescriptorsFromProtocol(a.Response.AllowedCredentials),
+ UserVerification: a.Response.UserVerification,
+ Extensions: a.Response.Extensions,
+ },
+ }
+}
+
+func credentialDescriptorsFromProtocol(cs []protocol.CredentialDescriptor) []CredentialDescriptor {
+ if len(cs) == 0 {
+ return nil
+ }
+
+ res := make([]CredentialDescriptor, len(cs))
+ for i, c := range cs {
+ res[i] = CredentialDescriptor{
+ Type: c.Type,
+ CredentialID: c.CredentialID,
+ Transport: c.Transport,
+ AttestationType: c.AttestationType,
+ }
+ }
+ return res
+}
+
+// CredentialAssertionResponse is the reply from authenticators to complete
+// login.
+type CredentialAssertionResponse struct {
+ // CredentialAssertionResponse is redefined because, unlike
+ // CredentialAssertion, it is likely to be manually created by package users.
+ // Redefining allows us to 1) make sure it can be properly JSON-marshaled
+ // (protocol.CredentialAssertionResponse.Extensions can't) and 2) we avoid
+ // leaking the duo-labs/webauthn dependency.
+ // The nesting of types is identical to protocol.CredentialAssertionResponse.
+
+ PublicKeyCredential
+ AssertionResponse AuthenticatorAssertionResponse `json:"response"`
+}
+
+// AuthenticatorAssertionResponse is a clone of
+// [protocol.AuthenticatorAssertionResponse], materialized here to keep a
+// stable JSON marshal/unmarshal representation.
+type AuthenticatorAssertionResponse struct {
+ AuthenticatorResponse
+ AuthenticatorData protocol.URLEncodedBase64 `json:"authenticatorData"`
+ Signature protocol.URLEncodedBase64 `json:"signature"`
+ UserHandle protocol.URLEncodedBase64 `json:"userHandle,omitempty"`
+}
+
+// AuthenticatorResponse is a clone of [protocol.AuthenticatorResponse],
+// materialized here to keep a stable JSON marshal/unmarshal representation.
+type AuthenticatorResponse protocol.AuthenticatorResponse
+
+// CredentialCreation is the payload sent to authenticators to initiate
+// registration.
+type CredentialCreation struct {
+ Response PublicKeyCredentialCreationOptions `json:"publicKey"`
+}
+
+// PublicKeyCredentialCreationOptions is a clone of
+// [protocol.PublicKeyCredentialCreationOptions], materialized here to keep a
+// stable JSON marshal/unmarshal representation.
+type PublicKeyCredentialCreationOptions struct {
+ Challenge Challenge `json:"challenge"`
+ RelyingParty RelyingPartyEntity `json:"rp"`
+ User UserEntity `json:"user"`
+ Parameters []CredentialParameter `json:"pubKeyCredParams,omitempty"`
+ AuthenticatorSelection AuthenticatorSelection `json:"authenticatorSelection,omitempty"`
+ Timeout int `json:"timeout,omitempty"`
+ CredentialExcludeList []CredentialDescriptor `json:"excludeCredentials,omitempty"`
+ Extensions AuthenticationExtensions `json:"extensions,omitempty"`
+ Attestation protocol.ConveyancePreference `json:"attestation,omitempty"`
+}
+
+// RelyingPartyEntity is a clone of [protocol.RelyingPartyEntity], materialized
+// here to keep a stable JSON marshal/unmarshal representation.
+type RelyingPartyEntity struct {
+ CredentialEntity
+ ID string `json:"id"`
+}
+
+// UserEntity is a clone of [protocol.UserEntity], materialized here to keep a
+// stable JSON marshal/unmarshal representation.
+type UserEntity struct {
+ CredentialEntity
+ DisplayName string `json:"displayName,omitempty"`
+ ID []byte `json:"id"`
+}
+
+// CredentialEntity is a clone of [protocol.CredentialEntity], materialized here
+// to keep a stable JSON marshal/unmarshal representation.
+type CredentialEntity = protocol.CredentialEntity
+
+// CredentialParameter is a clone of
+// [protocol.CredentialParameter], materialized here to keep a stable JSON
+// marshal/unmarshal representation.
+type CredentialParameter struct {
+ Type protocol.CredentialType `json:"type"`
+ Algorithm webauthncose.COSEAlgorithmIdentifier `json:"alg"`
+}
+
+// AuthenticatorSelection is a clone of
+// [protocol.AuthenticatorSelection], materialized here to keep a stable JSON
+// marshal/unmarshal representation.
+type AuthenticatorSelection struct {
+ AuthenticatorAttachment protocol.AuthenticatorAttachment `json:"authenticatorAttachment,omitempty"`
+ RequireResidentKey *bool `json:"requireResidentKey,omitempty"`
+ ResidentKey protocol.ResidentKeyRequirement `json:"residentKey,omitempty"`
+ UserVerification protocol.UserVerificationRequirement `json:"userVerification,omitempty"`
+}
+
+// AuthenticationExtensions is a clone of [protocol.AuthenticationExtensions],
+// materialized here to keep a stable JSON marshal/unmarshal representation.
+type AuthenticationExtensions = protocol.AuthenticationExtensions
+
+// RequireResidentKey returns information whether resident key is required or
+// not. It checks ResidentKey and fallbacks to RequireResidentKey.
+func (cc *CredentialCreation) RequireResidentKey() (bool, error) {
+ as := cc.Response.AuthenticatorSelection
+ switch as.ResidentKey {
+ case protocol.ResidentKeyRequirementRequired:
+ if as.RequireResidentKey != nil && !*as.RequireResidentKey {
+ return false, trace.BadParameter("invalid combination of ResidentKey: %v and RequireResidentKey: %v", as.ResidentKey, *as.RequireResidentKey)
+ }
+ return true, nil
+ case protocol.ResidentKeyRequirementDiscouraged:
+ if as.RequireResidentKey != nil && *as.RequireResidentKey {
+ return false, trace.BadParameter("invalid combination of ResidentKey: %v and RequireResidentKey: %v", as.ResidentKey, *as.RequireResidentKey)
+ }
+ return false, nil
+ case protocol.ResidentKeyRequirementPreferred:
+ return false, nil
+ }
+ // If ResidentKey is not set, then fallback to the legacy RequireResidentKey
+ // field.
+ return as.RequireResidentKey != nil && *as.RequireResidentKey, nil
+}
+
+// Validate performs client-side validation of CredentialCreation.
+// It makes sure that data are valid and can be sent to authenticator.
+// This is general purpose validation and authenticator should add its own
+// on top of it, if necessary.
+func (cc *CredentialCreation) Validate() error {
+ switch {
+ case cc == nil:
+ return trace.BadParameter("credential creation required")
+ case len(cc.Response.Challenge) == 0:
+ return trace.BadParameter("credential creation challenge required")
+ case cc.Response.RelyingParty.ID == "":
+ return trace.BadParameter("credential creation relying party ID required")
+ case len(cc.Response.RelyingParty.Name) == 0:
+ return trace.BadParameter("relying party name required")
+ case len(cc.Response.User.Name) == 0:
+ return trace.BadParameter("user name required")
+ case len(cc.Response.User.DisplayName) == 0:
+ return trace.BadParameter("user display name required")
+ case len(cc.Response.User.ID) == 0:
+ return trace.BadParameter("user ID required")
+ default:
+ return nil
+ }
+}
+
+// CredentialCreationFromProtocol converts a [protocol.CredentialCreation] to a
+// [CredentialCreation].
+func CredentialCreationFromProtocol(cc *protocol.CredentialCreation) *CredentialCreation {
+ if cc == nil {
+ return nil
+ }
+
+ return &CredentialCreation{
+ Response: PublicKeyCredentialCreationOptions{
+ Challenge: Challenge(cc.Response.Challenge),
+ RelyingParty: RelyingPartyEntity{
+ CredentialEntity: cc.Response.RelyingParty.CredentialEntity,
+ ID: cc.Response.RelyingParty.ID,
+ },
+ User: UserEntity{
+ CredentialEntity: cc.Response.User.CredentialEntity,
+ DisplayName: cc.Response.User.Name,
+ ID: cc.Response.User.ID,
+ },
+ Parameters: credentialParametersFromProtocol(cc.Response.Parameters),
+ AuthenticatorSelection: AuthenticatorSelection{
+ AuthenticatorAttachment: cc.Response.AuthenticatorSelection.AuthenticatorAttachment,
+ RequireResidentKey: cc.Response.AuthenticatorSelection.RequireResidentKey,
+ ResidentKey: cc.Response.AuthenticatorSelection.ResidentKey,
+ UserVerification: cc.Response.AuthenticatorSelection.UserVerification,
+ },
+ Timeout: cc.Response.Timeout,
+ CredentialExcludeList: credentialDescriptorsFromProtocol(cc.Response.CredentialExcludeList),
+ Extensions: cc.Response.Extensions,
+ Attestation: cc.Response.Attestation,
+ },
+ }
+}
+
+func credentialParametersFromProtocol(ps []protocol.CredentialParameter) []CredentialParameter {
+ if len(ps) == 0 {
+ return nil
+ }
+
+ res := make([]CredentialParameter, len(ps))
+ for i, p := range ps {
+ res[i] = CredentialParameter{
+ Type: p.Type,
+ Algorithm: p.Algorithm,
+ }
+ }
+ return res
+}
+
+// CredentialCreationResponse is the reply from authenticators to complete
+// registration.
+type CredentialCreationResponse struct {
+ // CredentialCreationResponse is manually redefined, instead of directly based
+ // in protocol.CredentialCreationResponse, for the same reasoning that
+ // CredentialAssertionResponse is - in short, we want a clean package.
+ // The nesting of types is identical to protocol.CredentialCreationResponse.
+
+ PublicKeyCredential
+ AttestationResponse AuthenticatorAttestationResponse `json:"response"`
+}
+
+// AuthenticatorAttestationResponse is a clone of
+// [protocol.AuthenticatorAttestationResponse], materialized here to keep a
+// stable JSON marshal/unmarshal representation.
+type AuthenticatorAttestationResponse struct {
+ AuthenticatorResponse
+ AttestationObject protocol.URLEncodedBase64 `json:"attestationObject"`
+
+ // Added by go-webauthn/webauthn v0.7.2.
+ // Transports []string `json:"transports,omitempty"`
+}
+
+// Challenge represents a WebAuthn challenge.
+// It is used instead of [protocol.URLEncodedBase64] so its JSON
+// marshal/unmarshal representation won't change in relation to older Teleport
+// versions.
+type Challenge []byte
+
+func CreateChallenge() (Challenge, error) {
+ chal, err := protocol.CreateChallenge()
+ if err != nil {
+ return nil, err
+ }
+ return Challenge(chal), nil
+}
+
+func (c Challenge) String() string {
+ return base64.RawURLEncoding.EncodeToString(c)
+}
+
+// CredentialDescriptor is a clone of [protocol.CredentialDescriptor],
+// materialized here to keep a stable JSON marshal/unmarshal representation.
+type CredentialDescriptor struct {
+ Type protocol.CredentialType `json:"type"`
+ CredentialID []byte `json:"id"`
+ Transport []protocol.AuthenticatorTransport `json:"transports,omitempty"`
+ AttestationType string `json:"-"`
+}
+
+// PublicKeyCredential is a clone of [protocol.PublicKeyCredential],
+// materialized here to keep a stable JSON marshal/unmarshal representation.
+type PublicKeyCredential struct {
+ Credential
+ RawID protocol.URLEncodedBase64 `json:"rawId"`
+ Extensions *AuthenticationExtensionsClientOutputs `json:"extensions,omitempty"`
+
+ // Added by go-webauthn/webauthn v0.7.2.
+ // AuthenticatorAttachment string `json:"authenticatorAttachment,omitempty"`
+}
+
+// Credential is a clone of [protocol.Credential], materialized here to keep a
+// stable JSON marshal/unmarshal representation.
+type Credential protocol.Credential
+
+// AuthenticationExtensionsClientOutputs is a clone of
+// [protocol.AuthenticationExtensionsClientOutputs], materialized here to keep a
+// stable JSON marshal/unmarshal representation.
+type AuthenticationExtensionsClientOutputs struct {
+ AppID bool `json:"appid,omitempty"`
+}
diff --git a/lib/auth/webauthn/messages_test.go b/lib/auth/webauthntypes/webauthn_test.go
similarity index 75%
rename from lib/auth/webauthn/messages_test.go
rename to lib/auth/webauthntypes/webauthn_test.go
index 19808f4aaa50e..a7f578e08dbeb 100644
--- a/lib/auth/webauthn/messages_test.go
+++ b/lib/auth/webauthntypes/webauthn_test.go
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package webauthn_test
+package webauthntypes_test
import (
"encoding/base64"
@@ -25,23 +25,23 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
- wanlib "github.com/gravitational/teleport/lib/auth/webauthn"
+ wantypes "github.com/gravitational/teleport/lib/auth/webauthntypes"
)
func TestCredentialAssertionResponse_json(t *testing.T) {
- resp := &wanlib.CredentialAssertionResponse{
- PublicKeyCredential: wanlib.PublicKeyCredential{
- Credential: wanlib.Credential{
+ resp := &wantypes.CredentialAssertionResponse{
+ PublicKeyCredential: wantypes.PublicKeyCredential{
+ Credential: wantypes.Credential{
ID: base64.RawURLEncoding.EncodeToString([]byte("credentialid")),
Type: "public-key",
},
RawID: []byte("credentialid"),
- Extensions: &wanlib.AuthenticationExtensionsClientOutputs{
+ Extensions: &wantypes.AuthenticationExtensionsClientOutputs{
AppID: true,
},
},
- AssertionResponse: wanlib.AuthenticatorAssertionResponse{
- AuthenticatorResponse: wanlib.AuthenticatorResponse{
+ AssertionResponse: wantypes.AuthenticatorAssertionResponse{
+ AuthenticatorResponse: wantypes.AuthenticatorResponse{
ClientDataJSON: []byte("clientdatajson"),
},
AuthenticatorData: []byte("authdata"),
@@ -53,7 +53,7 @@ func TestCredentialAssertionResponse_json(t *testing.T) {
respJSON, err := json.Marshal(resp)
require.NoError(t, err)
- got := &wanlib.CredentialAssertionResponse{}
+ got := &wantypes.CredentialAssertionResponse{}
require.NoError(t, json.Unmarshal(respJSON, got))
if diff := cmp.Diff(resp, got); diff != "" {
t.Errorf("Unmarshal() mismatch (-want +got):\n%s", diff)
@@ -61,24 +61,24 @@ func TestCredentialAssertionResponse_json(t *testing.T) {
}
func TestCredentialCreation_Validate(t *testing.T) {
- okCC := &wanlib.CredentialCreation{
- Response: protocol.PublicKeyCredentialCreationOptions{
+ okCC := &wantypes.CredentialCreation{
+ Response: wantypes.PublicKeyCredentialCreationOptions{
Challenge: make([]byte, 32),
- RelyingParty: protocol.RelyingPartyEntity{
+ RelyingParty: wantypes.RelyingPartyEntity{
ID: "example.com",
- CredentialEntity: protocol.CredentialEntity{
+ CredentialEntity: wantypes.CredentialEntity{
Name: "Teleport",
},
},
- Parameters: []protocol.CredentialParameter{
+ Parameters: []wantypes.CredentialParameter{
{Type: protocol.PublicKeyCredentialType, Algorithm: webauthncose.AlgES256},
},
- AuthenticatorSelection: protocol.AuthenticatorSelection{
+ AuthenticatorSelection: wantypes.AuthenticatorSelection{
UserVerification: protocol.VerificationDiscouraged,
},
Attestation: protocol.PreferNoAttestation,
- User: protocol.UserEntity{
- CredentialEntity: protocol.CredentialEntity{
+ User: wantypes.UserEntity{
+ CredentialEntity: wantypes.CredentialEntity{
Name: "llama",
},
DisplayName: "Llama",
@@ -89,23 +89,23 @@ func TestCredentialCreation_Validate(t *testing.T) {
tests := []struct {
name string
- createCC func() *wanlib.CredentialCreation
+ createCC func() *wantypes.CredentialCreation
alwaysCreateRK bool
wantErr string
}{
{
name: "ok", // check that good params are good
- createCC: func() *wanlib.CredentialCreation { return okCC },
+ createCC: func() *wantypes.CredentialCreation { return okCC },
wantErr: "",
},
{
name: "nil cc",
- createCC: func() *wanlib.CredentialCreation { return nil },
+ createCC: func() *wantypes.CredentialCreation { return nil },
wantErr: "credential creation required",
},
{
name: "nil challenge",
- createCC: func() *wanlib.CredentialCreation {
+ createCC: func() *wantypes.CredentialCreation {
cp := *okCC
cp.Response.Challenge = nil
return &cp
@@ -114,7 +114,7 @@ func TestCredentialCreation_Validate(t *testing.T) {
},
{
name: "empty RPID",
- createCC: func() *wanlib.CredentialCreation {
+ createCC: func() *wantypes.CredentialCreation {
cp := *okCC
cp.Response.RelyingParty.ID = ""
return &cp
@@ -123,7 +123,7 @@ func TestCredentialCreation_Validate(t *testing.T) {
},
{
name: "empty RP name",
- createCC: func() *wanlib.CredentialCreation {
+ createCC: func() *wantypes.CredentialCreation {
cp := *okCC
cp.Response.RelyingParty.Name = ""
return &cp
@@ -132,7 +132,7 @@ func TestCredentialCreation_Validate(t *testing.T) {
},
{
name: "empty user name",
- createCC: func() *wanlib.CredentialCreation {
+ createCC: func() *wantypes.CredentialCreation {
cp := *okCC
cp.Response.User.Name = ""
return &cp
@@ -141,7 +141,7 @@ func TestCredentialCreation_Validate(t *testing.T) {
},
{
name: "empty user display name",
- createCC: func() *wanlib.CredentialCreation {
+ createCC: func() *wantypes.CredentialCreation {
cp := *okCC
cp.Response.User.DisplayName = ""
return &cp
@@ -150,7 +150,7 @@ func TestCredentialCreation_Validate(t *testing.T) {
},
{
name: "nil user ID",
- createCC: func() *wanlib.CredentialCreation {
+ createCC: func() *wantypes.CredentialCreation {
cp := *okCC
cp.Response.User.ID = nil
return &cp
@@ -171,11 +171,11 @@ func TestCredentialCreation_Validate(t *testing.T) {
}
func TestCredentialAssertion_Validate(t *testing.T) {
- okAssertion := &wanlib.CredentialAssertion{
- Response: protocol.PublicKeyCredentialRequestOptions{
+ okAssertion := &wantypes.CredentialAssertion{
+ Response: wantypes.PublicKeyCredentialRequestOptions{
Challenge: make([]byte, 32),
RelyingPartyID: "example.com",
- AllowedCredentials: []protocol.CredentialDescriptor{
+ AllowedCredentials: []wantypes.CredentialDescriptor{
{Type: protocol.PublicKeyCredentialType, CredentialID: []byte{1, 2, 3, 4, 5}},
},
},
@@ -188,7 +188,7 @@ func TestCredentialAssertion_Validate(t *testing.T) {
emptyRPIDAssertion.Response.RelyingPartyID = ""
tests := []struct {
name string
- assertion *wanlib.CredentialAssertion
+ assertion *wantypes.CredentialAssertion
wantErr string
}{
{
@@ -226,18 +226,18 @@ func TestCredentialAssertion_Validate(t *testing.T) {
func TestRequireResidentKey(t *testing.T) {
tests := []struct {
name string
- in protocol.AuthenticatorSelection
+ in wantypes.AuthenticatorSelection
want bool
wantErr string
}{
{
name: "nothing set",
- in: protocol.AuthenticatorSelection{},
+ in: wantypes.AuthenticatorSelection{},
want: false,
},
{
name: "discouraged and rrk=true",
- in: protocol.AuthenticatorSelection{
+ in: wantypes.AuthenticatorSelection{
ResidentKey: protocol.ResidentKeyRequirementDiscouraged,
RequireResidentKey: protocol.ResidentKeyRequired(),
},
@@ -245,7 +245,7 @@ func TestRequireResidentKey(t *testing.T) {
},
{
name: "required and rrk=false",
- in: protocol.AuthenticatorSelection{
+ in: wantypes.AuthenticatorSelection{
ResidentKey: protocol.ResidentKeyRequirementRequired,
RequireResidentKey: protocol.ResidentKeyNotRequired(),
},
@@ -253,7 +253,7 @@ func TestRequireResidentKey(t *testing.T) {
},
{
name: "support nil RequireResidentKey",
- in: protocol.AuthenticatorSelection{
+ in: wantypes.AuthenticatorSelection{
ResidentKey: "",
RequireResidentKey: nil,
},
@@ -261,7 +261,7 @@ func TestRequireResidentKey(t *testing.T) {
},
{
name: "ResidentKey preferred result in false",
- in: protocol.AuthenticatorSelection{
+ in: wantypes.AuthenticatorSelection{
ResidentKey: protocol.ResidentKeyRequirementPreferred,
RequireResidentKey: nil,
},
@@ -269,21 +269,21 @@ func TestRequireResidentKey(t *testing.T) {
},
{
name: "ResidentKey required",
- in: protocol.AuthenticatorSelection{
+ in: wantypes.AuthenticatorSelection{
ResidentKey: protocol.ResidentKeyRequirementRequired,
},
want: true,
},
{
name: "ResidentKey discouraged",
- in: protocol.AuthenticatorSelection{
+ in: wantypes.AuthenticatorSelection{
ResidentKey: protocol.ResidentKeyRequirementDiscouraged,
},
want: false,
},
{
name: "use RequireResidentKey required if ResidentKey empty",
- in: protocol.AuthenticatorSelection{
+ in: wantypes.AuthenticatorSelection{
ResidentKey: "",
RequireResidentKey: protocol.ResidentKeyRequired(),
},
@@ -292,8 +292,8 @@ func TestRequireResidentKey(t *testing.T) {
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
- req := &wanlib.CredentialCreation{
- Response: protocol.PublicKeyCredentialCreationOptions{
+ req := &wantypes.CredentialCreation{
+ Response: wantypes.PublicKeyCredentialCreationOptions{
AuthenticatorSelection: test.in,
},
}
diff --git a/lib/auth/webauthnwin/api.go b/lib/auth/webauthnwin/api.go
index a9597c68d3a92..3a216eba62148 100644
--- a/lib/auth/webauthnwin/api.go
+++ b/lib/auth/webauthnwin/api.go
@@ -31,7 +31,7 @@ import (
log "github.com/sirupsen/logrus"
"github.com/gravitational/teleport/api/client/proto"
- wanlib "github.com/gravitational/teleport/lib/auth/webauthn"
+ wantypes "github.com/gravitational/teleport/lib/auth/webauthntypes"
)
// LoginOpts groups non-mandatory options for Login.
@@ -52,8 +52,8 @@ const (
// Implementors must provide a global variable called `native`.
type nativeWebauthn interface {
CheckSupport() CheckSupportResult
- GetAssertion(origin string, in *getAssertionRequest) (*wanlib.CredentialAssertionResponse, error)
- MakeCredential(origin string, in *makeCredentialRequest) (*wanlib.CredentialCreationResponse, error)
+ GetAssertion(origin string, in *getAssertionRequest) (*wantypes.CredentialAssertionResponse, error)
+ MakeCredential(origin string, in *makeCredentialRequest) (*wantypes.CredentialCreationResponse, error)
}
type getAssertionRequest struct {
@@ -73,7 +73,7 @@ type makeCredentialRequest struct {
}
// Login implements Login for Windows Webauthn API.
-func Login(_ context.Context, origin string, assertion *wanlib.CredentialAssertion, loginOpts *LoginOpts) (*proto.MFAAuthenticateResponse, string, error) {
+func Login(_ context.Context, origin string, assertion *wantypes.CredentialAssertion, loginOpts *LoginOpts) (*proto.MFAAuthenticateResponse, string, error) {
if origin == "" {
return nil, "", trace.BadParameter("origin required")
}
@@ -106,13 +106,13 @@ func Login(_ context.Context, origin string, assertion *wanlib.CredentialAsserti
return &proto.MFAAuthenticateResponse{
Response: &proto.MFAAuthenticateResponse_Webauthn{
- Webauthn: wanlib.CredentialAssertionResponseToProto(resp),
+ Webauthn: wantypes.CredentialAssertionResponseToProto(resp),
},
}, "", nil
}
// Register implements Register for Windows Webauthn API.
-func Register(_ context.Context, origin string, cc *wanlib.CredentialCreation) (*proto.MFARegisterResponse, error) {
+func Register(_ context.Context, origin string, cc *wantypes.CredentialCreation) (*proto.MFARegisterResponse, error) {
if origin == "" {
return nil, trace.BadParameter("origin required")
}
@@ -155,7 +155,7 @@ func Register(_ context.Context, origin string, cc *wanlib.CredentialCreation) (
return &proto.MFARegisterResponse{
Response: &proto.MFARegisterResponse_Webauthn{
- Webauthn: wanlib.CredentialCreationResponseToProto(resp),
+ Webauthn: wantypes.CredentialCreationResponseToProto(resp),
},
}, nil
}
@@ -224,23 +224,23 @@ func Diag(ctx context.Context) (*DiagResult, error) {
// Attempt registration.
const origin = "localhost"
- cc := &wanlib.CredentialCreation{
- Response: protocol.PublicKeyCredentialCreationOptions{
+ cc := &wantypes.CredentialCreation{
+ Response: wantypes.PublicKeyCredentialCreationOptions{
Challenge: make([]byte, 32),
- RelyingParty: protocol.RelyingPartyEntity{
+ RelyingParty: wantypes.RelyingPartyEntity{
ID: "localhost",
- CredentialEntity: protocol.CredentialEntity{
+ CredentialEntity: wantypes.CredentialEntity{
Name: "test RP",
},
},
- User: protocol.UserEntity{
- CredentialEntity: protocol.CredentialEntity{
+ User: wantypes.UserEntity{
+ CredentialEntity: wantypes.CredentialEntity{
Name: "test",
},
ID: []byte("test"),
DisplayName: "test",
},
- Parameters: []protocol.CredentialParameter{
+ Parameters: []wantypes.CredentialParameter{
{
Type: protocol.PublicKeyCredentialType,
Algorithm: webauthncose.AlgES256,
@@ -260,11 +260,11 @@ func Diag(ctx context.Context) (*DiagResult, error) {
res.RegisterSuccessful = true
// Attempt login.
- assertion := &wanlib.CredentialAssertion{
- Response: protocol.PublicKeyCredentialRequestOptions{
+ assertion := &wantypes.CredentialAssertion{
+ Response: wantypes.PublicKeyCredentialRequestOptions{
Challenge: make([]byte, 32),
RelyingPartyID: cc.Response.RelyingParty.ID,
- AllowedCredentials: []protocol.CredentialDescriptor{
+ AllowedCredentials: []wantypes.CredentialDescriptor{
{
Type: protocol.PublicKeyCredentialType,
CredentialID: ccr.GetWebauthn().GetRawId(),
diff --git a/lib/auth/webauthnwin/api_test.go b/lib/auth/webauthnwin/api_test.go
index 1aa4e254977fd..b6ccb06502cdc 100644
--- a/lib/auth/webauthnwin/api_test.go
+++ b/lib/auth/webauthnwin/api_test.go
@@ -25,8 +25,8 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
- "github.com/gravitational/teleport/api/types/webauthn"
- wanlib "github.com/gravitational/teleport/lib/auth/webauthn"
+ wanpb "github.com/gravitational/teleport/api/types/webauthn"
+ wantypes "github.com/gravitational/teleport/lib/auth/webauthntypes"
)
func init() {
@@ -38,27 +38,27 @@ func TestRegister(t *testing.T) {
resetNativeAfterTests(t)
const origin = "https://example.com"
- okCC := &wanlib.CredentialCreation{
- Response: protocol.PublicKeyCredentialCreationOptions{
+ okCC := &wantypes.CredentialCreation{
+ Response: wantypes.PublicKeyCredentialCreationOptions{
Challenge: make([]byte, 32),
- RelyingParty: protocol.RelyingPartyEntity{
+ RelyingParty: wantypes.RelyingPartyEntity{
ID: "example.com",
- CredentialEntity: protocol.CredentialEntity{
+ CredentialEntity: wantypes.CredentialEntity{
Name: "Teleport",
},
},
- User: protocol.UserEntity{
+ User: wantypes.UserEntity{
ID: []byte{1, 2, 3, 4},
DisplayName: "display name",
- CredentialEntity: protocol.CredentialEntity{
+ CredentialEntity: wantypes.CredentialEntity{
Name: "user name",
},
},
- Parameters: []protocol.CredentialParameter{
+ Parameters: []wantypes.CredentialParameter{
{Type: protocol.PublicKeyCredentialType, Algorithm: webauthncose.AlgES256},
{Type: protocol.PublicKeyCredentialType, Algorithm: webauthncose.AlgRS256},
},
- AuthenticatorSelection: protocol.AuthenticatorSelection{
+ AuthenticatorSelection: wantypes.AuthenticatorSelection{
UserVerification: protocol.VerificationDiscouraged,
},
Attestation: protocol.PreferNoAttestation,
@@ -68,14 +68,14 @@ func TestRegister(t *testing.T) {
tests := []struct {
name string
origin string
- createCC func() *wanlib.CredentialCreation
- assertFn func(t *testing.T, ccr *webauthn.CredentialCreationResponse, req *makeCredentialRequest)
+ createCC func() *wantypes.CredentialCreation
+ assertFn func(t *testing.T, ccr *wanpb.CredentialCreationResponse, req *makeCredentialRequest)
}{
{
name: "flow with auto attachment and discouraged UV",
origin: origin,
- createCC: func() *wanlib.CredentialCreation { return okCC },
- assertFn: func(t *testing.T, ccr *webauthn.CredentialCreationResponse, req *makeCredentialRequest) {
+ createCC: func() *wantypes.CredentialCreation { return okCC },
+ assertFn: func(t *testing.T, ccr *wanpb.CredentialCreationResponse, req *makeCredentialRequest) {
assert.Equal(t, webauthnAttachmentAny, req.opts.dwAuthenticatorAttachment)
assert.Equal(t, webauthnUserVerificationDiscouraged, req.opts.dwUserVerificationRequirement)
@@ -86,7 +86,7 @@ func TestRegister(t *testing.T) {
{
name: "with UV required and cross-platform and RRK",
origin: origin,
- createCC: func() *wanlib.CredentialCreation {
+ createCC: func() *wantypes.CredentialCreation {
cc := *okCC
cc.Response.User.DisplayName = "display name"
cc.Response.AuthenticatorSelection.UserVerification = protocol.VerificationRequired
@@ -94,7 +94,7 @@ func TestRegister(t *testing.T) {
cc.Response.AuthenticatorSelection.ResidentKey = protocol.ResidentKeyRequirementRequired
return &cc
},
- assertFn: func(t *testing.T, ccr *webauthn.CredentialCreationResponse, req *makeCredentialRequest) {
+ assertFn: func(t *testing.T, ccr *wanpb.CredentialCreationResponse, req *makeCredentialRequest) {
assert.Equal(t, webauthnUserVerificationRequired, req.opts.dwUserVerificationRequirement)
assert.Equal(t, webauthnAttachmentCrossPlatform, req.opts.dwAuthenticatorAttachment)
@@ -105,13 +105,13 @@ func TestRegister(t *testing.T) {
{
name: "with UV preferred and platform",
origin: origin,
- createCC: func() *wanlib.CredentialCreation {
+ createCC: func() *wantypes.CredentialCreation {
cc := *okCC
cc.Response.AuthenticatorSelection.UserVerification = protocol.VerificationPreferred
cc.Response.AuthenticatorSelection.AuthenticatorAttachment = protocol.Platform
return &cc
},
- assertFn: func(t *testing.T, ccr *webauthn.CredentialCreationResponse, req *makeCredentialRequest) {
+ assertFn: func(t *testing.T, ccr *wanpb.CredentialCreationResponse, req *makeCredentialRequest) {
assert.Equal(t, webauthnUserVerificationPreferred, req.opts.dwUserVerificationRequirement)
assert.Equal(t, webauthnAttachmentPlatform, req.opts.dwAuthenticatorAttachment)
@@ -120,24 +120,24 @@ func TestRegister(t *testing.T) {
{
name: "with UV discouraged and platform",
origin: origin,
- createCC: func() *wanlib.CredentialCreation {
+ createCC: func() *wantypes.CredentialCreation {
cc := *okCC
cc.Response.AuthenticatorSelection.UserVerification = protocol.VerificationDiscouraged
return &cc
},
- assertFn: func(t *testing.T, ccr *webauthn.CredentialCreationResponse, req *makeCredentialRequest) {
+ assertFn: func(t *testing.T, ccr *wanpb.CredentialCreationResponse, req *makeCredentialRequest) {
assert.Equal(t, webauthnUserVerificationDiscouraged, req.opts.dwUserVerificationRequirement)
},
},
{
name: "RRK from RequireResidentKey if is empty ResidentKey",
origin: origin,
- createCC: func() *wanlib.CredentialCreation {
+ createCC: func() *wantypes.CredentialCreation {
cc := *okCC
cc.Response.AuthenticatorSelection.RequireResidentKey = protocol.ResidentKeyRequired()
return &cc
},
- assertFn: func(t *testing.T, ccr *webauthn.CredentialCreationResponse, req *makeCredentialRequest) {
+ assertFn: func(t *testing.T, ccr *wanpb.CredentialCreationResponse, req *makeCredentialRequest) {
assert.Equal(t, uint32(1), req.opts.bRequireResidentKey)
},
},
@@ -163,11 +163,11 @@ func TestLogin(t *testing.T) {
resetNativeAfterTests(t)
const origin = "https://example.com"
- okAssertion := &wanlib.CredentialAssertion{
- Response: protocol.PublicKeyCredentialRequestOptions{
+ okAssertion := &wantypes.CredentialAssertion{
+ Response: wantypes.PublicKeyCredentialRequestOptions{
Challenge: make([]byte, 32),
RelyingPartyID: "example.com",
- AllowedCredentials: []protocol.CredentialDescriptor{
+ AllowedCredentials: []wantypes.CredentialDescriptor{
{Type: protocol.PublicKeyCredentialType, CredentialID: []byte{1, 2, 3, 4, 5}},
},
UserVerification: protocol.VerificationDiscouraged,
@@ -177,16 +177,16 @@ func TestLogin(t *testing.T) {
tests := []struct {
name string
origin string
- assertionIn func() *wanlib.CredentialAssertion
+ assertionIn func() *wantypes.CredentialAssertion
opts LoginOpts
wantErr string
- assertFn func(t *testing.T, car *webauthn.CredentialAssertionResponse, req *getAssertionRequest)
+ assertFn func(t *testing.T, car *wanpb.CredentialAssertionResponse, req *getAssertionRequest)
}{
{
name: "uv discouraged, attachment auto",
origin: origin,
- assertionIn: func() *wanlib.CredentialAssertion { return okAssertion },
- assertFn: func(t *testing.T, car *webauthn.CredentialAssertionResponse, req *getAssertionRequest) {
+ assertionIn: func() *wantypes.CredentialAssertion { return okAssertion },
+ assertFn: func(t *testing.T, car *wanpb.CredentialAssertionResponse, req *getAssertionRequest) {
assert.Equal(t, uint32(6), req.opts.dwVersion)
assert.Equal(t, webauthnUserVerificationDiscouraged, req.opts.dwUserVerificationRequirement)
@@ -197,13 +197,13 @@ func TestLogin(t *testing.T) {
{
name: "uv required, attachment platform",
origin: origin,
- assertionIn: func() *wanlib.CredentialAssertion {
+ assertionIn: func() *wantypes.CredentialAssertion {
out := *okAssertion
out.Response.UserVerification = protocol.VerificationRequired
return &out
},
opts: LoginOpts{AuthenticatorAttachment: AttachmentPlatform},
- assertFn: func(t *testing.T, car *webauthn.CredentialAssertionResponse, req *getAssertionRequest) {
+ assertFn: func(t *testing.T, car *wanpb.CredentialAssertionResponse, req *getAssertionRequest) {
assert.Equal(t, uint32(6), req.opts.dwVersion)
assert.Equal(t, webauthnUserVerificationRequired, req.opts.dwUserVerificationRequirement)
@@ -214,13 +214,13 @@ func TestLogin(t *testing.T) {
{
name: "uv preferred, attachment cross-platform",
origin: origin,
- assertionIn: func() *wanlib.CredentialAssertion {
+ assertionIn: func() *wantypes.CredentialAssertion {
out := *okAssertion
out.Response.UserVerification = protocol.VerificationPreferred
return &out
},
opts: LoginOpts{AuthenticatorAttachment: AttachmentCrossPlatform},
- assertFn: func(t *testing.T, car *webauthn.CredentialAssertionResponse, req *getAssertionRequest) {
+ assertFn: func(t *testing.T, car *wanpb.CredentialAssertionResponse, req *getAssertionRequest) {
assert.Equal(t, uint32(6), req.opts.dwVersion)
assert.Equal(t, webauthnUserVerificationPreferred, req.opts.dwUserVerificationRequirement)
@@ -231,13 +231,13 @@ func TestLogin(t *testing.T) {
{
name: "uv discouraged",
origin: origin,
- assertionIn: func() *wanlib.CredentialAssertion {
+ assertionIn: func() *wantypes.CredentialAssertion {
out := *okAssertion
out.Response.UserVerification = protocol.VerificationDiscouraged
return &out
},
opts: LoginOpts{AuthenticatorAttachment: AttachmentCrossPlatform},
- assertFn: func(t *testing.T, car *webauthn.CredentialAssertionResponse, req *getAssertionRequest) {
+ assertFn: func(t *testing.T, car *wanpb.CredentialAssertionResponse, req *getAssertionRequest) {
assert.Equal(t, uint32(6), req.opts.dwVersion)
assert.Equal(t, webauthnUserVerificationDiscouraged, req.opts.dwUserVerificationRequirement)
@@ -280,12 +280,12 @@ func (m *mockNative) CheckSupport() CheckSupportResult {
}
}
-func (m *mockNative) GetAssertion(origin string, in *getAssertionRequest) (*wanlib.CredentialAssertionResponse, error) {
+func (m *mockNative) GetAssertion(origin string, in *getAssertionRequest) (*wantypes.CredentialAssertionResponse, error) {
m.getAssersionReq = in
- return &wanlib.CredentialAssertionResponse{}, nil
+ return &wantypes.CredentialAssertionResponse{}, nil
}
-func (m *mockNative) MakeCredential(origin string, in *makeCredentialRequest) (*wanlib.CredentialCreationResponse, error) {
+func (m *mockNative) MakeCredential(origin string, in *makeCredentialRequest) (*wantypes.CredentialCreationResponse, error) {
m.makeCredentialReq = in
- return &wanlib.CredentialCreationResponse{}, nil
+ return &wantypes.CredentialCreationResponse{}, nil
}
diff --git a/lib/auth/webauthnwin/conv.go b/lib/auth/webauthnwin/conv.go
index ad293b5bc1e8d..55e2cdf57bca5 100644
--- a/lib/auth/webauthnwin/conv.go
+++ b/lib/auth/webauthnwin/conv.go
@@ -22,9 +22,11 @@ import (
"github.com/go-webauthn/webauthn/protocol"
"github.com/gravitational/trace"
+
+ wantypes "github.com/gravitational/teleport/lib/auth/webauthntypes"
)
-func assertOptionsToCType(in protocol.PublicKeyCredentialRequestOptions, loginOpts *LoginOpts) (*webauthnAuthenticatorGetAssertionOptions, error) {
+func assertOptionsToCType(in wantypes.PublicKeyCredentialRequestOptions, loginOpts *LoginOpts) (*webauthnAuthenticatorGetAssertionOptions, error) {
allowCredList, err := credentialsExToCType(in.AllowedCredentials)
if err != nil {
return nil, err
@@ -53,7 +55,7 @@ func assertOptionsToCType(in protocol.PublicKeyCredentialRequestOptions, loginOp
}, nil
}
-func rpToCType(in protocol.RelyingPartyEntity) (*webauthnRPEntityInformation, error) {
+func rpToCType(in wantypes.RelyingPartyEntity) (*webauthnRPEntityInformation, error) {
if in.ID == "" {
return nil, trace.BadParameter("missing RelyingPartyEntity.Id")
}
@@ -68,22 +70,14 @@ func rpToCType(in protocol.RelyingPartyEntity) (*webauthnRPEntityInformation, er
if err != nil {
return nil, err
}
- var icon *uint16
- if in.Icon != "" {
- icon, err = utf16PtrFromString(in.Icon)
- if err != nil {
- return nil, err
- }
- }
return &webauthnRPEntityInformation{
dwVersion: 1,
pwszID: id,
pwszName: name,
- pwszIcon: icon,
}, nil
}
-func userToCType(in protocol.UserEntity) (*webauthnUserEntityInformation, error) {
+func userToCType(in wantypes.UserEntity) (*webauthnUserEntityInformation, error) {
if len(in.ID) == 0 {
return nil, trace.BadParameter("missing UserEntity.Id")
}
@@ -102,24 +96,16 @@ func userToCType(in protocol.UserEntity) (*webauthnUserEntityInformation, error)
return nil, err
}
}
- var icon *uint16
- if in.Icon != "" {
- icon, err = utf16PtrFromString(in.Icon)
- if err != nil {
- return nil, err
- }
- }
return &webauthnUserEntityInformation{
dwVersion: 1,
cbID: uint32(len(in.ID)),
pbID: &in.ID[0],
pwszName: name,
pwszDisplayName: displayName,
- pwszIcon: icon,
}, nil
}
-func credParamToCType(in []protocol.CredentialParameter) (*webauthnCoseCredentialParameters, error) {
+func credParamToCType(in []wantypes.CredentialParameter) (*webauthnCoseCredentialParameters, error) {
if len(in) == 0 {
return nil, trace.BadParameter("missing CredentialParameter")
}
@@ -174,7 +160,7 @@ func clientDataToCType(challenge, origin, cdType string) (*webauthnClientData, [
}, jsonCD, nil
}
-func credentialsExToCType(in []protocol.CredentialDescriptor) (*webauthnCredentialList, error) {
+func credentialsExToCType(in []wantypes.CredentialDescriptor) (*webauthnCredentialList, error) {
exCredList := make([]*webauthnCredentialEX, 0, len(in))
for _, e := range in {
if e.Type == "" {
@@ -270,7 +256,7 @@ func userVerificationToCType(in protocol.UserVerificationRequirement) uint32 {
}
}
-func requirePreferResidentKey(in protocol.AuthenticatorSelection) (requireRK bool, preferRK bool) {
+func requirePreferResidentKey(in wantypes.AuthenticatorSelection) (requireRK bool, preferRK bool) {
switch in.ResidentKey {
case protocol.ResidentKeyRequirementRequired:
return true, false
@@ -286,7 +272,7 @@ func requirePreferResidentKey(in protocol.AuthenticatorSelection) (requireRK boo
}
}
-func makeCredOptionsToCType(in protocol.PublicKeyCredentialCreationOptions) (*webauthnAuthenticatorMakeCredentialOptions, error) {
+func makeCredOptionsToCType(in wantypes.PublicKeyCredentialCreationOptions) (*webauthnAuthenticatorMakeCredentialOptions, error) {
exCredList, err := credentialsExToCType(in.CredentialExcludeList)
if err != nil {
return nil, err
diff --git a/lib/auth/webauthnwin/ctypes.go b/lib/auth/webauthnwin/ctypes.go
index 2da0c0a7e3948..a97113b45aebc 100644
--- a/lib/auth/webauthnwin/ctypes.go
+++ b/lib/auth/webauthnwin/ctypes.go
@@ -35,8 +35,6 @@ type webauthnRPEntityInformation struct {
// "Acme Corporation", "Widgets Inc" or "Awesome Site".
// This field is required.
pwszName *uint16
- // Optional URL pointing to RP's logo.
- pwszIcon *uint16
}
type webauthnUserEntityInformation struct {
@@ -48,9 +46,6 @@ type webauthnUserEntityInformation struct {
// "john.p.smith@example.com".
// It holds the Teleport user name.
pwszName *uint16
- // Optional URL that can be used to retrieve an image containing the user's current avatar,
- // or a data URI that contains the image data.
- pwszIcon *uint16
// For User: Contains the friendly name associated with the user account by the Relying Party, such as "John P. Smith".
pwszDisplayName *uint16
}
diff --git a/lib/auth/webauthnwin/webauthn_other.go b/lib/auth/webauthnwin/webauthn_other.go
index 6b557718413e7..35854f79e50b3 100644
--- a/lib/auth/webauthnwin/webauthn_other.go
+++ b/lib/auth/webauthnwin/webauthn_other.go
@@ -20,7 +20,7 @@ package webauthnwin
import (
"errors"
- wanlib "github.com/gravitational/teleport/lib/auth/webauthn"
+ wantypes "github.com/gravitational/teleport/lib/auth/webauthntypes"
)
var native nativeWebauthn = noopNative{}
@@ -35,10 +35,10 @@ func (n noopNative) CheckSupport() CheckSupportResult {
}
}
-func (n noopNative) GetAssertion(origin string, in *getAssertionRequest) (*wanlib.CredentialAssertionResponse, error) {
+func (n noopNative) GetAssertion(origin string, in *getAssertionRequest) (*wantypes.CredentialAssertionResponse, error) {
return nil, errUnavailable
}
-func (n noopNative) MakeCredential(origin string, in *makeCredentialRequest) (*wanlib.CredentialCreationResponse, error) {
+func (n noopNative) MakeCredential(origin string, in *makeCredentialRequest) (*wantypes.CredentialCreationResponse, error) {
return nil, errUnavailable
}
diff --git a/lib/auth/webauthnwin/webauthn_windows.go b/lib/auth/webauthnwin/webauthn_windows.go
index ac59071db044a..49d08e4773b0f 100644
--- a/lib/auth/webauthnwin/webauthn_windows.go
+++ b/lib/auth/webauthnwin/webauthn_windows.go
@@ -26,7 +26,7 @@ import (
log "github.com/sirupsen/logrus"
"golang.org/x/sys/windows"
- wanlib "github.com/gravitational/teleport/lib/auth/webauthn"
+ wantypes "github.com/gravitational/teleport/lib/auth/webauthntypes"
)
var (
@@ -100,7 +100,7 @@ func (n *nativeImpl) CheckSupport() CheckSupportResult {
// either security key or Windows Hello).
// It does not accept username - during passwordless login webauthn.dll provides
// its own dialog with credentials selection.
-func (n *nativeImpl) GetAssertion(origin string, in *getAssertionRequest) (*wanlib.CredentialAssertionResponse, error) {
+func (n *nativeImpl) GetAssertion(origin string, in *getAssertionRequest) (*wantypes.CredentialAssertionResponse, error) {
hwnd, err := getForegroundWindow()
if err != nil {
return nil, trace.Wrap(err)
@@ -132,19 +132,19 @@ func (n *nativeImpl) GetAssertion(origin string, in *getAssertionRequest) (*wanl
credential := bytesFromCBytes(out.Credential.cbID, out.Credential.pbID)
credType := windows.UTF16PtrToString(out.Credential.pwszCredentialType)
- return &wanlib.CredentialAssertionResponse{
- PublicKeyCredential: wanlib.PublicKeyCredential{
+ return &wantypes.CredentialAssertionResponse{
+ PublicKeyCredential: wantypes.PublicKeyCredential{
RawID: credential,
- Credential: wanlib.Credential{
+ Credential: wantypes.Credential{
ID: base64.RawURLEncoding.EncodeToString(credential),
Type: credType,
},
},
- AssertionResponse: wanlib.AuthenticatorAssertionResponse{
+ AssertionResponse: wantypes.AuthenticatorAssertionResponse{
AuthenticatorData: authData,
Signature: signature,
UserHandle: userID,
- AuthenticatorResponse: wanlib.AuthenticatorResponse{
+ AuthenticatorResponse: wantypes.AuthenticatorResponse{
ClientDataJSON: in.jsonEncodedClientData,
},
},
@@ -157,7 +157,7 @@ func (n *nativeImpl) GetAssertion(origin string, in *getAssertionRequest) (*wanl
// (using auto starts with Windows Hello but there is
// option to select other devices).
// Windows Hello keys are always resident.
-func (n *nativeImpl) MakeCredential(origin string, in *makeCredentialRequest) (*wanlib.CredentialCreationResponse, error) {
+func (n *nativeImpl) MakeCredential(origin string, in *makeCredentialRequest) (*wantypes.CredentialCreationResponse, error) {
hwnd, err := getForegroundWindow()
if err != nil {
return nil, trace.Wrap(err)
@@ -187,16 +187,16 @@ func (n *nativeImpl) MakeCredential(origin string, in *makeCredentialRequest) (*
credential := bytesFromCBytes(out.cbCredentialID, out.pbCredentialID)
- return &wanlib.CredentialCreationResponse{
- PublicKeyCredential: wanlib.PublicKeyCredential{
- Credential: wanlib.Credential{
+ return &wantypes.CredentialCreationResponse{
+ PublicKeyCredential: wantypes.PublicKeyCredential{
+ Credential: wantypes.Credential{
ID: base64.RawURLEncoding.EncodeToString(credential),
Type: string(protocol.PublicKeyCredentialType),
},
RawID: credential,
},
- AttestationResponse: wanlib.AuthenticatorAttestationResponse{
- AuthenticatorResponse: wanlib.AuthenticatorResponse{
+ AttestationResponse: wantypes.AuthenticatorAttestationResponse{
+ AuthenticatorResponse: wantypes.AuthenticatorResponse{
ClientDataJSON: in.jsonEncodedClientData,
},
AttestationObject: bytesFromCBytes(out.cbAttestationObject, out.pbAttestationObject),
diff --git a/lib/client/api_login_test.go b/lib/client/api_login_test.go
index e1b1c972a8cac..e1af337560d91 100644
--- a/lib/client/api_login_test.go
+++ b/lib/client/api_login_test.go
@@ -41,8 +41,8 @@ import (
"github.com/gravitational/teleport/api/types"
"github.com/gravitational/teleport/lib/auth"
"github.com/gravitational/teleport/lib/auth/mocku2f"
- wanlib "github.com/gravitational/teleport/lib/auth/webauthn"
wancli "github.com/gravitational/teleport/lib/auth/webauthncli"
+ wantypes "github.com/gravitational/teleport/lib/auth/webauthntypes"
"github.com/gravitational/teleport/lib/backend"
"github.com/gravitational/teleport/lib/client"
"github.com/gravitational/teleport/lib/cloud"
@@ -98,7 +98,7 @@ func TestTeleportClient_Login_local(t *testing.T) {
<-ctx.Done() // wait for timeout
return "", ctx.Err()
}
- noopWebauthnFn := func(ctx context.Context, origin string, assertion *wanlib.CredentialAssertion, prompt wancli.LoginPrompt) (*proto.MFAAuthenticateResponse, error) {
+ noopWebauthnFn := func(ctx context.Context, origin string, assertion *wantypes.CredentialAssertion, prompt wancli.LoginPrompt) (*proto.MFAAuthenticateResponse, error) {
<-ctx.Done() // wait for timeout
return nil, ctx.Err()
}
@@ -106,18 +106,18 @@ func TestTeleportClient_Login_local(t *testing.T) {
solveOTP := func(ctx context.Context) (string, error) {
return totp.GenerateCode(otpKey, clock.Now())
}
- solveWebauthn := func(ctx context.Context, origin string, assertion *wanlib.CredentialAssertion, prompt wancli.LoginPrompt) (*proto.MFAAuthenticateResponse, error) {
+ solveWebauthn := func(ctx context.Context, origin string, assertion *wantypes.CredentialAssertion, prompt wancli.LoginPrompt) (*proto.MFAAuthenticateResponse, error) {
car, err := device.SignAssertion(origin, assertion)
if err != nil {
return nil, err
}
return &proto.MFAAuthenticateResponse{
Response: &proto.MFAAuthenticateResponse_Webauthn{
- Webauthn: wanlib.CredentialAssertionResponseToProto(car),
+ Webauthn: wantypes.CredentialAssertionResponseToProto(car),
},
}, nil
}
- solvePwdless := func(ctx context.Context, origin string, assertion *wanlib.CredentialAssertion, prompt wancli.LoginPrompt) (*proto.MFAAuthenticateResponse, error) {
+ solvePwdless := func(ctx context.Context, origin string, assertion *wantypes.CredentialAssertion, prompt wancli.LoginPrompt) (*proto.MFAAuthenticateResponse, error) {
resp, err := solveWebauthn(ctx, origin, assertion, prompt)
if err == nil {
resp.GetWebauthn().Response.UserHandle = webID
@@ -129,7 +129,7 @@ func TestTeleportClient_Login_local(t *testing.T) {
userPINFn := func(ctx context.Context) (string, error) {
return pin, nil
}
- solvePIN := func(ctx context.Context, origin string, assertion *wanlib.CredentialAssertion, prompt wancli.LoginPrompt) (*proto.MFAAuthenticateResponse, error) {
+ solvePIN := func(ctx context.Context, origin string, assertion *wantypes.CredentialAssertion, prompt wancli.LoginPrompt) (*proto.MFAAuthenticateResponse, error) {
// Ask and verify the PIN. Usually the authenticator would verify the PIN,
// but we are faking it here.
got, err := prompt.PromptPIN()
@@ -158,7 +158,7 @@ func TestTeleportClient_Login_local(t *testing.T) {
name string
secondFactor constants.SecondFactorType
inputReader *prompt.FakeReader
- solveWebauthn func(ctx context.Context, origin string, assertion *wanlib.CredentialAssertion, prompt wancli.LoginPrompt) (*proto.MFAAuthenticateResponse, error)
+ solveWebauthn func(ctx context.Context, origin string, assertion *wantypes.CredentialAssertion, prompt wancli.LoginPrompt) (*proto.MFAAuthenticateResponse, error)
authConnector string
allowStdinHijack bool
preferOTP bool
@@ -190,7 +190,7 @@ func TestTeleportClient_Login_local(t *testing.T) {
name: "OTP preferred",
secondFactor: constants.SecondFactorOptional,
inputReader: prompt.NewFakeReader().AddString(password).AddReply(solveOTP),
- solveWebauthn: func(ctx context.Context, origin string, assertion *wanlib.CredentialAssertion, prompt wancli.LoginPrompt) (*proto.MFAAuthenticateResponse, error) {
+ solveWebauthn: func(ctx context.Context, origin string, assertion *wantypes.CredentialAssertion, prompt wancli.LoginPrompt) (*proto.MFAAuthenticateResponse, error) {
panic("this should not be called")
},
preferOTP: true,
@@ -249,7 +249,7 @@ func TestTeleportClient_Login_local(t *testing.T) {
inputReader: prompt.NewFakeReader().
AddString(password).
AddReply(solveOTP),
- solveWebauthn: func(ctx context.Context, origin string, assertion *wanlib.CredentialAssertion, prompt wancli.LoginPrompt) (*proto.MFAAuthenticateResponse, error) {
+ solveWebauthn: func(ctx context.Context, origin string, assertion *wantypes.CredentialAssertion, prompt wancli.LoginPrompt) (*proto.MFAAuthenticateResponse, error) {
panic("this should not be called")
},
preferOTP: true,
@@ -264,7 +264,7 @@ func TestTeleportClient_Login_local(t *testing.T) {
prompt.SetStdin(test.inputReader)
*client.PromptWebauthn = func(
ctx context.Context,
- origin string, assertion *wanlib.CredentialAssertion, prompt wancli.LoginPrompt, _ *wancli.LoginOpts,
+ origin string, assertion *wantypes.CredentialAssertion, prompt wancli.LoginPrompt, _ *wancli.LoginOpts,
) (*proto.MFAAuthenticateResponse, string, error) {
resp, err := test.solveWebauthn(ctx, origin, assertion, prompt)
return resp, "", err
@@ -617,7 +617,7 @@ func newStandaloneTeleport(t *testing.T, clock clockwork.Clock) *standaloneBundl
DeviceUsage: proto.DeviceUsage_DEVICE_USAGE_PASSWORDLESS,
})
require.NoError(t, err)
- cc := wanlib.CredentialCreationFromProto(res.GetWebauthn())
+ cc := wantypes.CredentialCreationFromProto(res.GetWebauthn())
webID := cc.Response.User.ID
device, err := mocku2f.Create()
require.NoError(t, err)
@@ -630,7 +630,7 @@ func newStandaloneTeleport(t *testing.T, clock clockwork.Clock) *standaloneBundl
NewPassword: []byte(password),
NewMFARegisterResponse: &proto.MFARegisterResponse{
Response: &proto.MFARegisterResponse_Webauthn{
- Webauthn: wanlib.CredentialCreationResponseToProto(ccr),
+ Webauthn: wantypes.CredentialCreationResponseToProto(ccr),
},
},
})
diff --git a/lib/client/mfa.go b/lib/client/mfa.go
index 5ef70e8653ef8..5adb73e6a8818 100644
--- a/lib/client/mfa.go
+++ b/lib/client/mfa.go
@@ -29,9 +29,9 @@ import (
oteltrace "go.opentelemetry.io/otel/trace"
"github.com/gravitational/teleport/api/client/proto"
- wanlib "github.com/gravitational/teleport/lib/auth/webauthn"
wancli "github.com/gravitational/teleport/lib/auth/webauthncli"
- "github.com/gravitational/teleport/lib/auth/webauthnwin"
+ wantypes "github.com/gravitational/teleport/lib/auth/webauthntypes"
+ wanwin "github.com/gravitational/teleport/lib/auth/webauthnwin"
"github.com/gravitational/teleport/lib/utils/prompt"
)
@@ -239,8 +239,8 @@ func PromptMFAChallenge(ctx context.Context, c *proto.MFAAuthenticateChallenge,
// Customize Windows prompt directly.
// Note that the platform popup is a modal and will only go away if
// canceled.
- webauthnwin.PromptPlatformMessage = "Follow the OS dialogs for platform authentication, or enter an OTP code here:"
- defer webauthnwin.ResetPromptPlatformMessage()
+ wanwin.PromptPlatformMessage = "Follow the OS dialogs for platform authentication, or enter an OTP code here:"
+ defer wanwin.ResetPromptPlatformMessage()
default: // Webauthn only
prompt.FirstTouchMessage = fmt.Sprintf("Tap any %ssecurity key", promptDevicePrefix)
@@ -250,7 +250,7 @@ func PromptMFAChallenge(ctx context.Context, c *proto.MFAAuthenticateChallenge,
otpWait.Wait()
}}
- resp, _, err := promptWebauthn(ctx, origin, wanlib.CredentialAssertionFromProto(c.WebauthnChallenge), mfaPrompt, &wancli.LoginOpts{
+ resp, _, err := promptWebauthn(ctx, origin, wantypes.CredentialAssertionFromProto(c.WebauthnChallenge), mfaPrompt, &wancli.LoginOpts{
AuthenticatorAttachment: opts.AuthenticatorAttachment,
})
respC <- response{kind: "WEBAUTHN", resp: resp, err: err}
@@ -286,7 +286,7 @@ func PromptMFAChallenge(ctx context.Context, c *proto.MFAAuthenticateChallenge,
type MFAAuthenticateChallenge struct {
// WebauthnChallenge contains a WebAuthn credential assertion used for
// login/authentication ceremonies.
- WebauthnChallenge *wanlib.CredentialAssertion `json:"webauthn_challenge"`
+ WebauthnChallenge *wantypes.CredentialAssertion `json:"webauthn_challenge"`
// TOTPChallenge specifies whether TOTP is supported for this user.
TOTPChallenge bool `json:"totp_challenge"`
}
@@ -297,7 +297,7 @@ func MakeAuthenticateChallenge(protoChal *proto.MFAAuthenticateChallenge) *MFAAu
TOTPChallenge: protoChal.GetTOTP() != nil,
}
if protoChal.GetWebauthnChallenge() != nil {
- chal.WebauthnChallenge = wanlib.CredentialAssertionFromProto(protoChal.WebauthnChallenge)
+ chal.WebauthnChallenge = wantypes.CredentialAssertionFromProto(protoChal.WebauthnChallenge)
}
return chal
}
@@ -309,7 +309,7 @@ type TOTPRegisterChallenge struct {
// MFARegisterChallenge is an MFA register challenge sent on new MFA register.
type MFARegisterChallenge struct {
// Webauthn contains webauthn challenge.
- Webauthn *wanlib.CredentialCreation `json:"webauthn"`
+ Webauthn *wantypes.CredentialCreation `json:"webauthn"`
// TOTP contains TOTP challenge.
TOTP *TOTPRegisterChallenge `json:"totp"`
}
@@ -325,7 +325,7 @@ func MakeRegisterChallenge(protoChal *proto.MFARegisterChallenge) *MFARegisterCh
}
case *proto.MFARegisterChallenge_Webauthn:
return &MFARegisterChallenge{
- Webauthn: wanlib.CredentialCreationFromProto(protoChal.GetWebauthn()),
+ Webauthn: wantypes.CredentialCreationFromProto(protoChal.GetWebauthn()),
}
}
return nil
diff --git a/lib/client/mfa_test.go b/lib/client/mfa_test.go
index b267853eaaac3..a68520d305f33 100644
--- a/lib/client/mfa_test.go
+++ b/lib/client/mfa_test.go
@@ -24,8 +24,8 @@ import (
"github.com/gravitational/teleport/api/client/proto"
wanpb "github.com/gravitational/teleport/api/types/webauthn"
- wanlib "github.com/gravitational/teleport/lib/auth/webauthn"
wancli "github.com/gravitational/teleport/lib/auth/webauthncli"
+ wantypes "github.com/gravitational/teleport/lib/auth/webauthntypes"
"github.com/gravitational/teleport/lib/client"
"github.com/gravitational/teleport/lib/utils/prompt"
)
@@ -45,7 +45,7 @@ func TestPromptMFAChallenge_usingNonRegisteredDevice(t *testing.T) {
})
// User always picks a non-registered device.
- *client.PromptWebauthn = func(ctx context.Context, origin string, assertion *wanlib.CredentialAssertion, prompt wancli.LoginPrompt, opts *wancli.LoginOpts) (*proto.MFAAuthenticateResponse, string, error) {
+ *client.PromptWebauthn = func(ctx context.Context, origin string, assertion *wantypes.CredentialAssertion, prompt wancli.LoginPrompt, opts *wancli.LoginOpts) (*proto.MFAAuthenticateResponse, string, error) {
return nil, "", wancli.ErrUsingNonRegisteredDevice
}
// Support always enabled.
diff --git a/lib/client/weblogin.go b/lib/client/weblogin.go
index 6ca06870ef304..65fe2d7ef191f 100644
--- a/lib/client/weblogin.go
+++ b/lib/client/weblogin.go
@@ -42,8 +42,8 @@ import (
"github.com/gravitational/teleport/api/types"
"github.com/gravitational/teleport/api/utils/keys"
"github.com/gravitational/teleport/lib/auth"
- wanlib "github.com/gravitational/teleport/lib/auth/webauthn"
wancli "github.com/gravitational/teleport/lib/auth/webauthncli"
+ wantypes "github.com/gravitational/teleport/lib/auth/webauthntypes"
"github.com/gravitational/teleport/lib/defaults"
)
@@ -104,7 +104,7 @@ type MFAChallengeResponse struct {
// TOTPCode is a code for a otp device.
TOTPCode string `json:"totp_code,omitempty"`
// WebauthnResponse is a response from a webauthn device.
- WebauthnResponse *wanlib.CredentialAssertionResponse `json:"webauthn_response,omitempty"`
+ WebauthnResponse *wantypes.CredentialAssertionResponse `json:"webauthn_response,omitempty"`
}
// GetOptionalMFAResponseProtoReq converts response to a type proto.MFAAuthenticateResponse,
@@ -122,7 +122,7 @@ func (r *MFAChallengeResponse) GetOptionalMFAResponseProtoReq() (*proto.MFAAuthe
if r.WebauthnResponse != nil {
return &proto.MFAAuthenticateResponse{Response: &proto.MFAAuthenticateResponse_Webauthn{
- Webauthn: wanlib.CredentialAssertionResponseToProto(r.WebauthnResponse),
+ Webauthn: wantypes.CredentialAssertionResponseToProto(r.WebauthnResponse),
}}, nil
}
@@ -167,7 +167,7 @@ type AuthenticateSSHUserRequest struct {
// performed.
Password string `json:"password"`
// WebauthnChallengeResponse is a signed WebAuthn credential assertion.
- WebauthnChallengeResponse *wanlib.CredentialAssertionResponse `json:"webauthn_challenge_response"`
+ WebauthnChallengeResponse *wantypes.CredentialAssertionResponse `json:"webauthn_challenge_response"`
// TOTPCode is a code from the TOTP device.
TOTPCode string `json:"totp_code"`
// PubKey is a public key user wishes to sign
@@ -191,14 +191,14 @@ type AuthenticateWebUserRequest struct {
// User is a teleport username.
User string `json:"user"`
// WebauthnAssertionResponse is a signed WebAuthn credential assertion.
- WebauthnAssertionResponse *wanlib.CredentialAssertionResponse `json:"webauthnAssertionResponse,omitempty"`
+ WebauthnAssertionResponse *wantypes.CredentialAssertionResponse `json:"webauthnAssertionResponse,omitempty"`
}
type HeadlessRequest struct {
// Actions can be either accept or deny.
Action string `json:"action"`
// WebauthnAssertionResponse is a signed WebAuthn credential assertion.
- WebauthnAssertionResponse *wanlib.CredentialAssertionResponse `json:"webauthnAssertionResponse,omitempty"`
+ WebauthnAssertionResponse *wantypes.CredentialAssertionResponse `json:"webauthnAssertionResponse,omitempty"`
}
// SSHLogin contains common SSH login parameters.
@@ -521,7 +521,7 @@ func SSHAgentPasswordlessLogin(ctx context.Context, login SSHLoginPasswordless)
ctx, webClient.Endpoint("webapi", "mfa", "login", "finish"),
&AuthenticateSSHUserRequest{
User: "", // User carried on WebAuthn assertion.
- WebauthnChallengeResponse: wanlib.CredentialAssertionResponseFromProto(mfaResp.GetWebauthn()),
+ WebauthnChallengeResponse: wantypes.CredentialAssertionResponseFromProto(mfaResp.GetWebauthn()),
PubKey: login.PubKey,
TTL: login.TTL,
Compatibility: login.Compatibility,
@@ -570,7 +570,7 @@ func SSHAgentMFALogin(ctx context.Context, login SSHLoginMFA) (*auth.SSHLoginRes
challengePB.TOTP = &proto.TOTPChallenge{}
}
if challenge.WebauthnChallenge != nil {
- challengePB.WebauthnChallenge = wanlib.CredentialAssertionToProto(challenge.WebauthnChallenge)
+ challengePB.WebauthnChallenge = wantypes.CredentialAssertionToProto(challenge.WebauthnChallenge)
}
respPB, err := PromptMFAChallenge(ctx, challengePB, login.ProxyAddr, &PromptMFAChallengeOpts{
@@ -597,7 +597,7 @@ func SSHAgentMFALogin(ctx context.Context, login SSHLoginMFA) (*auth.SSHLoginRes
case *proto.MFAAuthenticateResponse_TOTP:
challengeResp.TOTPCode = r.TOTP.Code
case *proto.MFAAuthenticateResponse_Webauthn:
- challengeResp.WebauthnChallengeResponse = wanlib.CredentialAssertionResponseFromProto(r.Webauthn)
+ challengeResp.WebauthnChallengeResponse = wantypes.CredentialAssertionResponseFromProto(r.Webauthn)
default:
// No challenge was sent, so we send back just username/password.
}
diff --git a/lib/client/weblogin_test.go b/lib/client/weblogin_test.go
index 984d925589d6e..ce6ae66df25b2 100644
--- a/lib/client/weblogin_test.go
+++ b/lib/client/weblogin_test.go
@@ -31,8 +31,8 @@ import (
"github.com/gravitational/teleport/api/client/proto"
"github.com/gravitational/teleport/api/types"
- wanlib "github.com/gravitational/teleport/lib/auth/webauthn"
wancli "github.com/gravitational/teleport/lib/auth/webauthncli"
+ wantypes "github.com/gravitational/teleport/lib/auth/webauthntypes"
"github.com/gravitational/teleport/lib/client"
)
@@ -139,14 +139,14 @@ func TestSSHAgentPasswordlessLogin(t *testing.T) {
*client.PromptWebauthn = oldWebauthn
})
- solvePwdless := func(ctx context.Context, origin string, assertion *wanlib.CredentialAssertion, prompt wancli.LoginPrompt) (*proto.MFAAuthenticateResponse, error) {
+ solvePwdless := func(ctx context.Context, origin string, assertion *wantypes.CredentialAssertion, prompt wancli.LoginPrompt) (*proto.MFAAuthenticateResponse, error) {
car, err := device.SignAssertion(origin, assertion)
if err != nil {
return nil, err
}
resp := &proto.MFAAuthenticateResponse{
Response: &proto.MFAAuthenticateResponse_Webauthn{
- Webauthn: wanlib.CredentialAssertionResponseToProto(car),
+ Webauthn: wantypes.CredentialAssertionResponseToProto(car),
},
}
resp.GetWebauthn().Response.UserHandle = webID
@@ -165,12 +165,12 @@ func TestSSHAgentPasswordlessLogin(t *testing.T) {
tests := []struct {
name string
- customPromptWebauthn func(ctx context.Context, origin string, assert *wanlib.CredentialAssertion, p wancli.LoginPrompt, _ *wancli.LoginOpts) (*proto.MFAAuthenticateResponse, string, error)
+ customPromptWebauthn func(ctx context.Context, origin string, assert *wantypes.CredentialAssertion, p wancli.LoginPrompt, _ *wancli.LoginOpts) (*proto.MFAAuthenticateResponse, string, error)
customPromptLogin wancli.LoginPrompt
}{
{
name: "with custom prompt",
- customPromptWebauthn: func(ctx context.Context, origin string, assert *wanlib.CredentialAssertion, p wancli.LoginPrompt, _ *wancli.LoginOpts) (*proto.MFAAuthenticateResponse, string, error) {
+ customPromptWebauthn: func(ctx context.Context, origin string, assert *wantypes.CredentialAssertion, p wancli.LoginPrompt, _ *wancli.LoginOpts) (*proto.MFAAuthenticateResponse, string, error) {
_, ok := p.(*customPromptLogin)
require.True(t, ok)
customPromptCalled = true
@@ -197,7 +197,7 @@ func TestSSHAgentPasswordlessLogin(t *testing.T) {
},
{
name: "without custom prompt",
- customPromptWebauthn: func(ctx context.Context, origin string, assert *wanlib.CredentialAssertion, p wancli.LoginPrompt, _ *wancli.LoginOpts) (*proto.MFAAuthenticateResponse, string, error) {
+ customPromptWebauthn: func(ctx context.Context, origin string, assert *wantypes.CredentialAssertion, p wancli.LoginPrompt, _ *wancli.LoginOpts) (*proto.MFAAuthenticateResponse, string, error) {
_, ok := p.(*wancli.DefaultPrompt)
require.True(t, ok)
customPromptCalled = true
diff --git a/lib/services/identity.go b/lib/services/identity.go
index 9812037da3b65..0a797eb7819e8 100644
--- a/lib/services/identity.go
+++ b/lib/services/identity.go
@@ -29,7 +29,7 @@ import (
"github.com/gravitational/teleport/api/client/proto"
"github.com/gravitational/teleport/api/types"
- wantypes "github.com/gravitational/teleport/api/types/webauthn"
+ wanpb "github.com/gravitational/teleport/api/types/webauthn"
"github.com/gravitational/teleport/api/utils/keys"
"github.com/gravitational/teleport/lib/defaults"
)
@@ -129,11 +129,11 @@ type Identity interface {
// storage, for the purpose of later verifying an authentication or
// registration challenge.
// Session data is expected to expire according to backend settings.
- UpsertWebauthnSessionData(ctx context.Context, user, sessionID string, sd *wantypes.SessionData) error
+ UpsertWebauthnSessionData(ctx context.Context, user, sessionID string, sd *wanpb.SessionData) error
// GetWebauthnSessionData retrieves a previously-stored session data by ID,
// if it exists and has not expired.
- GetWebauthnSessionData(ctx context.Context, user, sessionID string) (*wantypes.SessionData, error)
+ GetWebauthnSessionData(ctx context.Context, user, sessionID string) (*wanpb.SessionData, error)
// DeleteWebauthnSessionData deletes session data by ID, if it exists and has
// not expired.
@@ -143,12 +143,12 @@ type Identity interface {
// storage, for the purpose of later verifying an authentication challenge.
// Session data is expected to expire according to backend settings.
// Used for passwordless challenges.
- UpsertGlobalWebauthnSessionData(ctx context.Context, scope, id string, sd *wantypes.SessionData) error
+ UpsertGlobalWebauthnSessionData(ctx context.Context, scope, id string, sd *wanpb.SessionData) error
// GetGlobalWebauthnSessionData retrieves previously-stored session data by ID,
// if it exists and has not expired.
// Used for passwordless challenges.
- GetGlobalWebauthnSessionData(ctx context.Context, scope, id string) (*wantypes.SessionData, error)
+ GetGlobalWebauthnSessionData(ctx context.Context, scope, id string) (*wanpb.SessionData, error)
// DeleteGlobalWebauthnSessionData deletes session data by ID, if it exists
// and has not expired.
diff --git a/lib/services/local/users.go b/lib/services/local/users.go
index b5e2e0ab916b9..52cfea9b7dffe 100644
--- a/lib/services/local/users.go
+++ b/lib/services/local/users.go
@@ -38,7 +38,7 @@ import (
"golang.org/x/crypto/ssh"
"github.com/gravitational/teleport/api/types"
- wantypes "github.com/gravitational/teleport/api/types/webauthn"
+ wanpb "github.com/gravitational/teleport/api/types/webauthn"
"github.com/gravitational/teleport/api/utils/keys"
"github.com/gravitational/teleport/lib/backend"
"github.com/gravitational/teleport/lib/defaults"
@@ -616,7 +616,7 @@ func (s *IdentityService) UpsertWebauthnLocalAuth(ctx context.Context, user stri
if err != nil {
return trace.Wrap(err, "marshal webauthn local auth")
}
- userJSON, err := json.Marshal(&wantypes.User{
+ userJSON, err := json.Marshal(&wanpb.User{
TeleportUser: user,
})
if err != nil {
@@ -673,7 +673,7 @@ func (s *IdentityService) GetTeleportUserByWebauthnID(ctx context.Context, webID
if err != nil {
return "", trace.Wrap(err)
}
- user := &wantypes.User{}
+ user := &wanpb.User{}
if err := json.Unmarshal(item.Value, user); err != nil {
return "", trace.Wrap(err)
}
@@ -689,7 +689,7 @@ func webauthnUserKey(id []byte) []byte {
return backend.Key(webauthnPrefix, usersPrefix, key)
}
-func (s *IdentityService) UpsertWebauthnSessionData(ctx context.Context, user, sessionID string, sd *wantypes.SessionData) error {
+func (s *IdentityService) UpsertWebauthnSessionData(ctx context.Context, user, sessionID string, sd *wanpb.SessionData) error {
switch {
case user == "":
return trace.BadParameter("missing parameter user")
@@ -711,7 +711,7 @@ func (s *IdentityService) UpsertWebauthnSessionData(ctx context.Context, user, s
return trace.Wrap(err)
}
-func (s *IdentityService) GetWebauthnSessionData(ctx context.Context, user, sessionID string) (*wantypes.SessionData, error) {
+func (s *IdentityService) GetWebauthnSessionData(ctx context.Context, user, sessionID string) (*wanpb.SessionData, error) {
switch {
case user == "":
return nil, trace.BadParameter("missing parameter user")
@@ -723,7 +723,7 @@ func (s *IdentityService) GetWebauthnSessionData(ctx context.Context, user, sess
if err != nil {
return nil, trace.Wrap(err)
}
- sd := &wantypes.SessionData{}
+ sd := &wanpb.SessionData{}
return sd, trace.Wrap(json.Unmarshal(item.Value, sd))
}
@@ -784,7 +784,7 @@ var sdLimiter = &globalSessionDataLimiter{
scopeCount: make(map[string]int),
}
-func (s *IdentityService) UpsertGlobalWebauthnSessionData(ctx context.Context, scope, id string, sd *wantypes.SessionData) error {
+func (s *IdentityService) UpsertGlobalWebauthnSessionData(ctx context.Context, scope, id string, sd *wanpb.SessionData) error {
switch {
case scope == "":
return trace.BadParameter("missing parameter scope")
@@ -817,7 +817,7 @@ func (s *IdentityService) UpsertGlobalWebauthnSessionData(ctx context.Context, s
return nil
}
-func (s *IdentityService) GetGlobalWebauthnSessionData(ctx context.Context, scope, id string) (*wantypes.SessionData, error) {
+func (s *IdentityService) GetGlobalWebauthnSessionData(ctx context.Context, scope, id string) (*wanpb.SessionData, error) {
switch {
case scope == "":
return nil, trace.BadParameter("missing parameter scope")
@@ -829,7 +829,7 @@ func (s *IdentityService) GetGlobalWebauthnSessionData(ctx context.Context, scop
if err != nil {
return nil, trace.Wrap(err)
}
- sd := &wantypes.SessionData{}
+ sd := &wanpb.SessionData{}
return sd, trace.Wrap(json.Unmarshal(item.Value, sd))
}
diff --git a/lib/services/local/users_test.go b/lib/services/local/users_test.go
index c183dd5ec4376..48764449012c6 100644
--- a/lib/services/local/users_test.go
+++ b/lib/services/local/users_test.go
@@ -35,7 +35,7 @@ import (
"github.com/stretchr/testify/require"
"github.com/gravitational/teleport/api/types"
- wantypes "github.com/gravitational/teleport/api/types/webauthn"
+ wanpb "github.com/gravitational/teleport/api/types/webauthn"
"github.com/gravitational/teleport/api/utils/keys"
"github.com/gravitational/teleport/lib/auth/native"
"github.com/gravitational/teleport/lib/backend"
@@ -613,16 +613,16 @@ func TestIdentityService_WebauthnSessionDataCRUD(t *testing.T) {
const user2 = "alpaca"
// Prepare a few different objects so we can assert that both "user" and
// "session" key components are used correctly.
- user1Reg := &wantypes.SessionData{
+ user1Reg := &wanpb.SessionData{
Challenge: []byte("challenge1-reg"),
UserId: []byte("llamaid"),
}
- user1Login := &wantypes.SessionData{
+ user1Login := &wanpb.SessionData{
Challenge: []byte("challenge1-login"),
UserId: []byte("llamaid"),
AllowCredentials: [][]byte{[]byte("cred1"), []byte("cred2")},
}
- user2Login := &wantypes.SessionData{
+ user2Login := &wanpb.SessionData{
Challenge: []byte("challenge2"),
UserId: []byte("alpacaid"),
}
@@ -632,7 +632,7 @@ func TestIdentityService_WebauthnSessionDataCRUD(t *testing.T) {
const loginSession = "login"
params := []struct {
user, session string
- sd *wantypes.SessionData
+ sd *wanpb.SessionData
}{
{user: user1, session: registerSession, sd: user1Reg},
{user: user1, session: loginSession, sd: user1Login},
@@ -656,7 +656,7 @@ func TestIdentityService_WebauthnSessionDataCRUD(t *testing.T) {
}
// Verify upsert/update.
- user1Reg = &wantypes.SessionData{
+ user1Reg = &wanpb.SessionData{
Challenge: []byte("challenge1reg--another"),
UserId: []byte("llamaid"),
}
@@ -684,23 +684,23 @@ func TestIdentityService_GlobalWebauthnSessionDataCRUD(t *testing.T) {
t.Parallel()
identity := newIdentityService(t, clockwork.NewFakeClock())
- user1Login1 := &wantypes.SessionData{
+ user1Login1 := &wanpb.SessionData{
Challenge: []byte("challenge1"),
UserId: []byte("user1-web-id"),
UserVerification: string(protocol.VerificationRequired),
}
- user1Login2 := &wantypes.SessionData{
+ user1Login2 := &wanpb.SessionData{
Challenge: []byte("challenge2"),
UserId: []byte("user1-web-id"),
UserVerification: string(protocol.VerificationRequired),
}
- user1Registration := &wantypes.SessionData{
+ user1Registration := &wanpb.SessionData{
Challenge: []byte("challenge3"),
UserId: []byte("user1-web-id"),
ResidentKey: true,
UserVerification: string(protocol.VerificationRequired),
}
- user2Login := &wantypes.SessionData{
+ user2Login := &wanpb.SessionData{
Challenge: []byte("challenge4"),
UserId: []byte("user2-web-id"),
ResidentKey: true,
@@ -713,7 +713,7 @@ func TestIdentityService_GlobalWebauthnSessionDataCRUD(t *testing.T) {
const scopeRegister = "register"
params := []struct {
scope, id string
- sd *wantypes.SessionData
+ sd *wanpb.SessionData
}{
{scope: scopeLogin, id: base64.RawURLEncoding.EncodeToString(user1Login1.Challenge), sd: user1Login1},
{scope: scopeLogin, id: base64.RawURLEncoding.EncodeToString(user1Login2.Challenge), sd: user1Login2},
@@ -780,7 +780,7 @@ func TestIdentityService_UpsertGlobalWebauthnSessionData_maxLimit(t *testing.T)
const id2 = "challenge2"
const id3 = "challenge3"
const id4 = "challenge4"
- sd := &wantypes.SessionData{
+ sd := &wanpb.SessionData{
Challenge: []byte("supersecretchallenge"), // typically matches the key
UserVerification: "required",
}
diff --git a/lib/srv/desktop/tdp/proto.go b/lib/srv/desktop/tdp/proto.go
index c937e598b82ae..a35fdba3997f3 100644
--- a/lib/srv/desktop/tdp/proto.go
+++ b/lib/srv/desktop/tdp/proto.go
@@ -34,7 +34,7 @@ import (
"github.com/gravitational/trace"
authproto "github.com/gravitational/teleport/api/client/proto"
- wanlib "github.com/gravitational/teleport/lib/auth/webauthn"
+ wantypes "github.com/gravitational/teleport/lib/auth/webauthntypes"
"github.com/gravitational/teleport/lib/client"
"github.com/gravitational/teleport/lib/defaults"
"github.com/gravitational/teleport/lib/web/mfajson"
@@ -550,7 +550,7 @@ func (m MFA) Encode() ([]byte, error) {
} else if m.MFAAuthenticateResponse != nil {
switch t := m.MFAAuthenticateResponse.Response.(type) {
case *authproto.MFAAuthenticateResponse_Webauthn:
- buff, err = json.Marshal(wanlib.CredentialAssertionResponseFromProto(m.MFAAuthenticateResponse.GetWebauthn()))
+ buff, err = json.Marshal(wantypes.CredentialAssertionResponseFromProto(m.MFAAuthenticateResponse.GetWebauthn()))
if err != nil {
return nil, trace.Wrap(err)
}
diff --git a/lib/srv/desktop/tdp/proto_test.go b/lib/srv/desktop/tdp/proto_test.go
index 7f7b2119dc9eb..1a58bca28064f 100644
--- a/lib/srv/desktop/tdp/proto_test.go
+++ b/lib/srv/desktop/tdp/proto_test.go
@@ -31,8 +31,8 @@ import (
"github.com/stretchr/testify/require"
authproto "github.com/gravitational/teleport/api/client/proto"
- wantypes "github.com/gravitational/teleport/api/types/webauthn"
- wanlib "github.com/gravitational/teleport/lib/auth/webauthn"
+ wanpb "github.com/gravitational/teleport/api/types/webauthn"
+ wantypes "github.com/gravitational/teleport/lib/auth/webauthntypes"
"github.com/gravitational/teleport/lib/client"
"github.com/gravitational/teleport/lib/defaults"
)
@@ -125,12 +125,12 @@ func TestMFA(t *testing.T) {
mfaWant := &MFA{
Type: defaults.WebsocketWebauthnChallenge[0],
MFAAuthenticateChallenge: &client.MFAAuthenticateChallenge{
- WebauthnChallenge: &wanlib.CredentialAssertion{
- Response: protocol.PublicKeyCredentialRequestOptions{
+ WebauthnChallenge: &wantypes.CredentialAssertion{
+ Response: wantypes.PublicKeyCredentialRequestOptions{
Challenge: []byte("challenge"),
Timeout: 10,
RelyingPartyID: "teleport",
- AllowedCredentials: []protocol.CredentialDescriptor{
+ AllowedCredentials: []wantypes.CredentialDescriptor{
{
Type: "public-key",
CredentialID: []byte("credential id"),
@@ -138,7 +138,7 @@ func TestMFA(t *testing.T) {
},
},
UserVerification: "discouraged",
- Extensions: protocol.AuthenticationExtensions{
+ Extensions: wantypes.AuthenticationExtensions{
"ext1": "value1",
},
},
@@ -160,16 +160,16 @@ func TestMFA(t *testing.T) {
Type: defaults.WebsocketWebauthnChallenge[0],
MFAAuthenticateResponse: &authproto.MFAAuthenticateResponse{
Response: &authproto.MFAAuthenticateResponse_Webauthn{
- Webauthn: &wantypes.CredentialAssertionResponse{
+ Webauthn: &wanpb.CredentialAssertionResponse{
Type: "public-key",
RawId: []byte("credential id"),
- Response: &wantypes.AuthenticatorAssertionResponse{
+ Response: &wanpb.AuthenticatorAssertionResponse{
ClientDataJson: []byte("client data json"),
AuthenticatorData: []byte("authenticator data"),
Signature: []byte("signature"),
UserHandle: []byte("user handle"),
},
- Extensions: &wantypes.AuthenticationExtensionsClientOutputs{
+ Extensions: &wanpb.AuthenticationExtensionsClientOutputs{
AppId: true,
},
},
diff --git a/lib/web/apiserver.go b/lib/web/apiserver.go
index 9515d66834221..f63aea19c2098 100644
--- a/lib/web/apiserver.go
+++ b/lib/web/apiserver.go
@@ -67,7 +67,7 @@ import (
"github.com/gravitational/teleport/api/utils/keys"
apisshutils "github.com/gravitational/teleport/api/utils/sshutils"
"github.com/gravitational/teleport/lib/auth"
- wanlib "github.com/gravitational/teleport/lib/auth/webauthn"
+ wantypes "github.com/gravitational/teleport/lib/auth/webauthntypes"
"github.com/gravitational/teleport/lib/client"
"github.com/gravitational/teleport/lib/defaults"
dtconfig "github.com/gravitational/teleport/lib/devicetrust/config"
@@ -2038,7 +2038,7 @@ type changeUserAuthenticationRequest struct {
// Password is user password string converted to bytes.
Password []byte `json:"password"`
// WebauthnCreationResponse is the signed credential creation response.
- WebauthnCreationResponse *wanlib.CredentialCreationResponse `json:"webauthnCreationResponse"`
+ WebauthnCreationResponse *wantypes.CredentialCreationResponse `json:"webauthnCreationResponse"`
}
func (h *Handler) changeUserAuthentication(w http.ResponseWriter, r *http.Request, p httprouter.Params) (interface{}, error) {
@@ -2056,7 +2056,7 @@ func (h *Handler) changeUserAuthentication(w http.ResponseWriter, r *http.Reques
case req.WebauthnCreationResponse != nil:
protoReq.NewMFARegisterResponse = &proto.MFARegisterResponse{
Response: &proto.MFARegisterResponse_Webauthn{
- Webauthn: wanlib.CredentialCreationResponseToProto(req.WebauthnCreationResponse),
+ Webauthn: wantypes.CredentialCreationResponseToProto(req.WebauthnCreationResponse),
},
}
case req.SecondFactorToken != "":
diff --git a/lib/web/apiserver_login_test.go b/lib/web/apiserver_login_test.go
index 6231c6dafb071..c265107c0cc22 100644
--- a/lib/web/apiserver_login_test.go
+++ b/lib/web/apiserver_login_test.go
@@ -34,7 +34,7 @@ import (
"github.com/gravitational/teleport/api/types"
"github.com/gravitational/teleport/api/utils/keys"
"github.com/gravitational/teleport/lib/auth"
- wanlib "github.com/gravitational/teleport/lib/auth/webauthn"
+ wantypes "github.com/gravitational/teleport/lib/auth/webauthntypes"
"github.com/gravitational/teleport/lib/client"
"github.com/gravitational/teleport/lib/defaults"
"github.com/gravitational/teleport/lib/modules"
@@ -237,11 +237,11 @@ func TestAuthenticate_passwordless(t *testing.T) {
tests := []struct {
name string
- login func(t *testing.T, assertionResp *wanlib.CredentialAssertionResponse)
+ login func(t *testing.T, assertionResp *wantypes.CredentialAssertionResponse)
}{
{
name: "ssh",
- login: func(t *testing.T, assertionResp *wanlib.CredentialAssertionResponse) {
+ login: func(t *testing.T, assertionResp *wantypes.CredentialAssertionResponse) {
ep := clt.Endpoint("webapi", "mfa", "login", "finish")
sshResp, err := clt.PostJSON(ctx, ep, &client.AuthenticateSSHUserRequest{
WebauthnChallengeResponse: assertionResp, // no username
@@ -256,7 +256,7 @@ func TestAuthenticate_passwordless(t *testing.T) {
},
{
name: "web",
- login: func(t *testing.T, assertionResp *wanlib.CredentialAssertionResponse) {
+ login: func(t *testing.T, assertionResp *wantypes.CredentialAssertionResponse) {
ep := clt.Endpoint("webapi", "mfa", "login", "finishsession")
sessionResp, err := clt.PostJSON(ctx, ep, &client.AuthenticateWebUserRequest{
WebauthnAssertionResponse: assertionResp, // no username
diff --git a/lib/web/apiserver_test.go b/lib/web/apiserver_test.go
index e4c71c74bf5fd..5a3b6bd293df0 100644
--- a/lib/web/apiserver_test.go
+++ b/lib/web/apiserver_test.go
@@ -96,7 +96,7 @@ import (
"github.com/gravitational/teleport/lib/auth/mocku2f"
"github.com/gravitational/teleport/lib/auth/native"
"github.com/gravitational/teleport/lib/auth/testauthority"
- wanlib "github.com/gravitational/teleport/lib/auth/webauthn"
+ wantypes "github.com/gravitational/teleport/lib/auth/webauthntypes"
"github.com/gravitational/teleport/lib/authz"
"github.com/gravitational/teleport/lib/bpf"
"github.com/gravitational/teleport/lib/client"
@@ -1697,12 +1697,12 @@ func TestTerminalRequireSessionMFA(t *testing.T) {
},
getChallengeResponseBytes: func(chals *client.MFAAuthenticateChallenge, dev *auth.TestDevice) []byte {
res, err := dev.SolveAuthn(&authproto.MFAAuthenticateChallenge{
- WebauthnChallenge: wanlib.CredentialAssertionToProto(chals.WebauthnChallenge),
+ WebauthnChallenge: wantypes.CredentialAssertionToProto(chals.WebauthnChallenge),
})
require.Nil(t, err)
- webauthnResBytes, err := json.Marshal(wanlib.CredentialAssertionResponseFromProto(res.GetWebauthn()))
- require.Nil(t, err)
+ webauthnResBytes, err := json.Marshal(wantypes.CredentialAssertionResponseFromProto(res.GetWebauthn()))
+ require.NoError(t, err)
return webauthnResBytes
},
@@ -1901,7 +1901,7 @@ func handleMFAWebauthnChallenge(t *testing.T, ws *websocket.Conn, dev *auth.Test
mfaChallange, err := tdp.DecodeMFAChallenge(br)
require.NoError(t, err)
res, err := dev.SolveAuthn(&authproto.MFAAuthenticateChallenge{
- WebauthnChallenge: wanlib.CredentialAssertionToProto(mfaChallange.WebauthnChallenge),
+ WebauthnChallenge: wantypes.CredentialAssertionToProto(mfaChallange.WebauthnChallenge),
})
require.NoError(t, err)
err = tdp.NewConn(&WebsocketIO{Conn: ws}).WriteMessage(tdp.MFA{
@@ -4251,7 +4251,7 @@ func TestAddMFADevice(t *testing.T) {
name string
deviceName string
getTOTPCode func() string
- getWebauthnResp func() *wanlib.CredentialCreationResponse
+ getWebauthnResp func() *wantypes.CredentialCreationResponse
}{
{
name: "new TOTP device",
@@ -4273,7 +4273,7 @@ func TestAddMFADevice(t *testing.T) {
{
name: "new Webauthn device",
deviceName: "new-webauthn",
- getWebauthnResp: func() *wanlib.CredentialCreationResponse {
+ getWebauthnResp: func() *wantypes.CredentialCreationResponse {
// Get webauthn register challenge.
res, err := env.server.Auth().CreateRegisterChallenge(ctx, &authproto.CreateRegisterChallengeRequest{
TokenID: privilegeToken,
@@ -4284,7 +4284,7 @@ func TestAddMFADevice(t *testing.T) {
_, regRes, err := auth.NewTestDeviceFromChallenge(res)
require.NoError(t, err)
- return wanlib.CredentialCreationResponseFromProto(regRes.GetWebauthn())
+ return wantypes.CredentialCreationResponseFromProto(regRes.GetWebauthn())
},
},
}
@@ -4294,7 +4294,7 @@ func TestAddMFADevice(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
var totpCode string
- var webauthnRegResp *wanlib.CredentialCreationResponse
+ var webauthnRegResp *wantypes.CredentialCreationResponse
if tc.getWebauthnResp != nil {
webauthnRegResp = tc.getWebauthnResp()
@@ -5208,7 +5208,7 @@ func TestChangeUserAuthentication_settingDefaultClusterAuthPreference(t *testing
})
require.NoError(t, err)
- cc := wanlib.CredentialCreationFromProto(res.GetWebauthn())
+ cc := wantypes.CredentialCreationFromProto(res.GetWebauthn())
// use passwordless as auth method
device, err := mocku2f.Create()
diff --git a/lib/web/files.go b/lib/web/files.go
index cb442b0075898..f579beff1283f 100644
--- a/lib/web/files.go
+++ b/lib/web/files.go
@@ -29,7 +29,7 @@ import (
"github.com/gravitational/teleport/api/defaults"
"github.com/gravitational/teleport/api/types"
"github.com/gravitational/teleport/lib/auth"
- wanlib "github.com/gravitational/teleport/lib/auth/webauthn"
+ wantypes "github.com/gravitational/teleport/lib/auth/webauthntypes"
"github.com/gravitational/teleport/lib/client"
"github.com/gravitational/teleport/lib/reversetunnel"
"github.com/gravitational/teleport/lib/sshutils/sftp"
@@ -184,7 +184,7 @@ func (f *fileTransfer) createClient(req fileTransferRequest, httpReq *http.Reque
type mfaRequest struct {
// WebauthnResponse is the response from authenticators.
- WebauthnAssertionResponse *wanlib.CredentialAssertionResponse `json:"webauthnAssertionResponse"`
+ WebauthnAssertionResponse *wantypes.CredentialAssertionResponse `json:"webauthnAssertionResponse"`
}
// issueSingleUseCert will take an assertion response sent from a solved challenge in the web UI
@@ -209,7 +209,7 @@ func (f *fileTransfer) issueSingleUseCert(webauthn string, httpReq *http.Request
Expires: time.Now().Add(time.Minute).UTC(),
MFAResponse: &proto.MFAAuthenticateResponse{
Response: &proto.MFAAuthenticateResponse_Webauthn{
- Webauthn: wanlib.CredentialAssertionResponseToProto(mfaReq.WebauthnAssertionResponse),
+ Webauthn: wantypes.CredentialAssertionResponseToProto(mfaReq.WebauthnAssertionResponse),
},
},
})
diff --git a/lib/web/headless.go b/lib/web/headless.go
index 527bec83b33fd..4cab41fda017a 100644
--- a/lib/web/headless.go
+++ b/lib/web/headless.go
@@ -27,7 +27,7 @@ import (
"github.com/gravitational/teleport/api/client/proto"
"github.com/gravitational/teleport/api/types"
- wanlib "github.com/gravitational/teleport/lib/auth/webauthn"
+ wantypes "github.com/gravitational/teleport/lib/auth/webauthntypes"
"github.com/gravitational/teleport/lib/client"
"github.com/gravitational/teleport/lib/httplib"
)
@@ -76,7 +76,7 @@ func (h *Handler) putHeadlessState(_ http.ResponseWriter, r *http.Request, param
action = types.HeadlessAuthenticationState_HEADLESS_AUTHENTICATION_STATE_APPROVED
resp = &proto.MFAAuthenticateResponse{
Response: &proto.MFAAuthenticateResponse_Webauthn{
- Webauthn: wanlib.CredentialAssertionResponseToProto(req.WebauthnAssertionResponse),
+ Webauthn: wantypes.CredentialAssertionResponseToProto(req.WebauthnAssertionResponse),
},
}
case "denied":
diff --git a/lib/web/mfa.go b/lib/web/mfa.go
index b9cd7ca7fde68..a0f5b6812cee0 100644
--- a/lib/web/mfa.go
+++ b/lib/web/mfa.go
@@ -24,7 +24,7 @@ import (
"github.com/julienschmidt/httprouter"
"github.com/gravitational/teleport/api/client/proto"
- "github.com/gravitational/teleport/lib/auth/webauthn"
+ wantypes "github.com/gravitational/teleport/lib/auth/webauthntypes"
"github.com/gravitational/teleport/lib/client"
"github.com/gravitational/teleport/lib/httplib"
"github.com/gravitational/teleport/lib/reversetunnel"
@@ -78,7 +78,7 @@ type addMFADeviceRequest struct {
// SecondFactorToken is the totp code.
SecondFactorToken string `json:"secondFactorToken"`
// WebauthnRegisterResponse is a WebAuthn registration challenge response.
- WebauthnRegisterResponse *webauthn.CredentialCreationResponse `json:"webauthnRegisterResponse"`
+ WebauthnRegisterResponse *wantypes.CredentialCreationResponse `json:"webauthnRegisterResponse"`
// DeviceUsage is the intended usage of the device (MFA, Passwordless, etc).
// It mimics the proto.DeviceUsage enum.
// Defaults to MFA.
@@ -110,7 +110,7 @@ func (h *Handler) addMFADeviceHandle(w http.ResponseWriter, r *http.Request, par
}}
case req.WebauthnRegisterResponse != nil:
protoReq.NewMFAResponse = &proto.MFARegisterResponse{Response: &proto.MFARegisterResponse_Webauthn{
- Webauthn: webauthn.CredentialCreationResponseToProto(req.WebauthnRegisterResponse),
+ Webauthn: wantypes.CredentialCreationResponseToProto(req.WebauthnRegisterResponse),
}}
default:
return nil, trace.BadParameter("missing new mfa credentials")
diff --git a/lib/web/mfajson/mfajson.go b/lib/web/mfajson/mfajson.go
index 09b6c6aa32f35..474df03f14006 100644
--- a/lib/web/mfajson/mfajson.go
+++ b/lib/web/mfajson/mfajson.go
@@ -22,7 +22,7 @@ import (
"github.com/gravitational/trace"
authproto "github.com/gravitational/teleport/api/client/proto"
- wanlib "github.com/gravitational/teleport/lib/auth/webauthn"
+ wantypes "github.com/gravitational/teleport/lib/auth/webauthntypes"
"github.com/gravitational/teleport/lib/defaults"
)
@@ -33,13 +33,13 @@ func Decode(b []byte, typ string) (*authproto.MFAAuthenticateResponse, error) {
switch typ {
case defaults.WebsocketWebauthnChallenge:
- var webauthnResponse wanlib.CredentialAssertionResponse
+ var webauthnResponse wantypes.CredentialAssertionResponse
if err := json.Unmarshal(b, &webauthnResponse); err != nil {
return nil, trace.Wrap(err)
}
resp = &authproto.MFAAuthenticateResponse{
Response: &authproto.MFAAuthenticateResponse_Webauthn{
- Webauthn: wanlib.CredentialAssertionResponseToProto(&webauthnResponse),
+ Webauthn: wantypes.CredentialAssertionResponseToProto(&webauthnResponse),
},
}
diff --git a/lib/web/password.go b/lib/web/password.go
index 00ec6c874b639..00a624ad25b71 100644
--- a/lib/web/password.go
+++ b/lib/web/password.go
@@ -23,7 +23,7 @@ import (
"github.com/julienschmidt/httprouter"
"github.com/gravitational/teleport/api/client/proto"
- wanlib "github.com/gravitational/teleport/lib/auth/webauthn"
+ wantypes "github.com/gravitational/teleport/lib/auth/webauthntypes"
"github.com/gravitational/teleport/lib/client"
"github.com/gravitational/teleport/lib/httplib"
)
@@ -37,7 +37,7 @@ type changePasswordReq struct {
// SecondFactorToken is user 2nd factor token
SecondFactorToken string `json:"second_factor_token"`
// WebauthnAssertionResponse is a Webauthn response
- WebauthnAssertionResponse *wanlib.CredentialAssertionResponse `json:"webauthnAssertionResponse"`
+ WebauthnAssertionResponse *wantypes.CredentialAssertionResponse `json:"webauthnAssertionResponse"`
}
// changePassword updates users password based on the old password.
@@ -57,7 +57,7 @@ func (h *Handler) changePassword(w http.ResponseWriter, r *http.Request, p httpr
OldPassword: req.OldPassword,
NewPassword: req.NewPassword,
SecondFactorToken: req.SecondFactorToken,
- Webauthn: wanlib.CredentialAssertionResponseToProto(
+ Webauthn: wantypes.CredentialAssertionResponseToProto(
req.WebauthnAssertionResponse,
),
}
diff --git a/lib/web/terminal.go b/lib/web/terminal.go
index 80bfd0643f962..fb317cb07eaa2 100644
--- a/lib/web/terminal.go
+++ b/lib/web/terminal.go
@@ -46,7 +46,7 @@ import (
"github.com/gravitational/teleport/api/types"
"github.com/gravitational/teleport/api/utils/keys"
"github.com/gravitational/teleport/lib/auth"
- wanlib "github.com/gravitational/teleport/lib/auth/webauthn"
+ wantypes "github.com/gravitational/teleport/lib/auth/webauthntypes"
"github.com/gravitational/teleport/lib/client"
"github.com/gravitational/teleport/lib/defaults"
"github.com/gravitational/teleport/lib/events"
@@ -609,7 +609,7 @@ func promptMFAChallenge(
switch {
case c.GetWebauthnChallenge() != nil:
challenge = &client.MFAAuthenticateChallenge{
- WebauthnChallenge: wanlib.CredentialAssertionFromProto(c.WebauthnChallenge),
+ WebauthnChallenge: wantypes.CredentialAssertionFromProto(c.WebauthnChallenge),
}
default:
return nil, trace.AccessDenied("only hardware keys are supported on the web terminal, please register a hardware device to connect to this server")
diff --git a/lib/web/users.go b/lib/web/users.go
index 3f0d56ca559a0..35ed56c8702dc 100644
--- a/lib/web/users.go
+++ b/lib/web/users.go
@@ -26,7 +26,7 @@ import (
"github.com/gravitational/teleport/api/client/proto"
"github.com/gravitational/teleport/api/types"
- wanlib "github.com/gravitational/teleport/lib/auth/webauthn"
+ wantypes "github.com/gravitational/teleport/lib/auth/webauthntypes"
"github.com/gravitational/teleport/lib/httplib"
"github.com/gravitational/teleport/lib/web/ui"
)
@@ -221,7 +221,7 @@ type privilegeTokenRequest struct {
// SecondFactorToken is the totp code.
SecondFactorToken string `json:"secondFactorToken"`
// WebauthnResponse is the response from authenticators.
- WebauthnResponse *wanlib.CredentialAssertionResponse `json:"webauthnAssertionResponse"`
+ WebauthnResponse *wantypes.CredentialAssertionResponse `json:"webauthnAssertionResponse"`
}
// createPrivilegeTokenHandle creates and returns a privilege token.
@@ -240,7 +240,7 @@ func (h *Handler) createPrivilegeTokenHandle(w http.ResponseWriter, r *http.Requ
}}
case req.WebauthnResponse != nil:
protoReq.ExistingMFAResponse = &proto.MFAAuthenticateResponse{Response: &proto.MFAAuthenticateResponse_Webauthn{
- Webauthn: wanlib.CredentialAssertionResponseToProto(req.WebauthnResponse),
+ Webauthn: wantypes.CredentialAssertionResponseToProto(req.WebauthnResponse),
}}
default:
// Can be empty, which means user did not have a second factor registered.
diff --git a/tool/tsh/mfa.go b/tool/tsh/mfa.go
index 6871603f0d96e..eb72ea56decfb 100644
--- a/tool/tsh/mfa.go
+++ b/tool/tsh/mfa.go
@@ -35,9 +35,9 @@ import (
"github.com/gravitational/teleport/api/types"
"github.com/gravitational/teleport/lib/asciitable"
"github.com/gravitational/teleport/lib/auth/touchid"
- wanlib "github.com/gravitational/teleport/lib/auth/webauthn"
wancli "github.com/gravitational/teleport/lib/auth/webauthncli"
- "github.com/gravitational/teleport/lib/auth/webauthnwin"
+ wantypes "github.com/gravitational/teleport/lib/auth/webauthntypes"
+ wanwin "github.com/gravitational/teleport/lib/auth/webauthnwin"
"github.com/gravitational/teleport/lib/client"
"github.com/gravitational/teleport/lib/defaults"
"github.com/gravitational/teleport/lib/utils"
@@ -358,8 +358,8 @@ func (c *mfaAddCommand) addDeviceRPC(ctx context.Context, tc *client.TeleportCli
// of finding out whether it is a Windows prompt or not).
const registeredMsg = "Using platform authentication for *registered* device, follow the OS dialogs"
const newMsg = "Using platform authentication for *new* device, follow the OS dialogs"
- defer webauthnwin.ResetPromptPlatformMessage()
- webauthnwin.PromptPlatformMessage = registeredMsg
+ defer wanwin.ResetPromptPlatformMessage()
+ wanwin.PromptPlatformMessage = registeredMsg
authResp, err := tc.PromptMFAChallenge(ctx, "" /* proxyAddr */, authChallenge, func(opts *client.PromptMFAChallengeOpts) {
opts.PromptDevicePrefix = "*registered* "
@@ -383,7 +383,7 @@ func (c *mfaAddCommand) addDeviceRPC(ctx context.Context, tc *client.TeleportCli
return trace.BadParameter("server bug: server sent %T when client expected AddMFADeviceResponse_NewMFARegisterChallenge", resp.Response)
}
- webauthnwin.PromptPlatformMessage = newMsg
+ wanwin.PromptPlatformMessage = newMsg
regResp, regCallback, err := promptRegisterChallenge(ctx, tc.WebProxyAddr, c.devType, regChallenge)
if err != nil {
return trace.Wrap(err)
@@ -441,7 +441,7 @@ func promptRegisterChallenge(ctx context.Context, proxyAddr, devType string, c *
if !strings.HasPrefix(proxyAddr, "https://") {
origin = "https://" + origin
}
- cc := wanlib.CredentialCreationFromProto(c.GetWebauthn())
+ cc := wantypes.CredentialCreationFromProto(c.GetWebauthn())
if devType == touchIDDeviceType {
return promptTouchIDRegisterChallenge(origin, cc)
@@ -531,7 +531,7 @@ func promptTOTPRegisterChallenge(ctx context.Context, c *proto.TOTPRegisterChall
}}, nil
}
-func promptWebauthnRegisterChallenge(ctx context.Context, origin string, cc *wanlib.CredentialCreation) (*proto.MFARegisterResponse, error) {
+func promptWebauthnRegisterChallenge(ctx context.Context, origin string, cc *wantypes.CredentialCreation) (*proto.MFARegisterResponse, error) {
log.Debugf("WebAuthn: prompting MFA devices with origin %q", origin)
prompt := wancli.NewDefaultPrompt(ctx, os.Stdout)
@@ -543,7 +543,7 @@ func promptWebauthnRegisterChallenge(ctx context.Context, origin string, cc *wan
return resp, trace.Wrap(err)
}
-func promptTouchIDRegisterChallenge(origin string, cc *wanlib.CredentialCreation) (*proto.MFARegisterResponse, registerCallback, error) {
+func promptTouchIDRegisterChallenge(origin string, cc *wantypes.CredentialCreation) (*proto.MFARegisterResponse, registerCallback, error) {
log.Debugf("Touch ID: prompting registration with origin %q", origin)
reg, err := touchid.Register(origin, cc)
@@ -552,7 +552,7 @@ func promptTouchIDRegisterChallenge(origin string, cc *wanlib.CredentialCreation
}
return &proto.MFARegisterResponse{
Response: &proto.MFARegisterResponse_Webauthn{
- Webauthn: wanlib.CredentialCreationResponseToProto(reg.CCR),
+ Webauthn: wantypes.CredentialCreationResponseToProto(reg.CCR),
},
}, reg, nil
}
diff --git a/tool/tsh/tsh_test.go b/tool/tsh/tsh_test.go
index 4e90d9ddc86ba..84127f9cc2675 100644
--- a/tool/tsh/tsh_test.go
+++ b/tool/tsh/tsh_test.go
@@ -60,8 +60,8 @@ import (
"github.com/gravitational/teleport/lib"
"github.com/gravitational/teleport/lib/auth"
"github.com/gravitational/teleport/lib/auth/mocku2f"
- wanlib "github.com/gravitational/teleport/lib/auth/webauthn"
wancli "github.com/gravitational/teleport/lib/auth/webauthncli"
+ wantypes "github.com/gravitational/teleport/lib/auth/webauthntypes"
"github.com/gravitational/teleport/lib/backend"
"github.com/gravitational/teleport/lib/client"
"github.com/gravitational/teleport/lib/client/identityfile"
@@ -1125,7 +1125,7 @@ func TestSSHOnMultipleNodes(t *testing.T) {
DeviceUsage: proto.DeviceUsage_DEVICE_USAGE_PASSWORDLESS,
})
require.NoError(t, err)
- cc := wanlib.CredentialCreationFromProto(res.GetWebauthn())
+ cc := wantypes.CredentialCreationFromProto(res.GetWebauthn())
ccr, err := device.SignCredentialCreation(origin(cluster), cc)
require.NoError(t, err)
@@ -1134,7 +1134,7 @@ func TestSSHOnMultipleNodes(t *testing.T) {
NewPassword: []byte(password),
NewMFARegisterResponse: &proto.MFARegisterResponse{
Response: &proto.MFARegisterResponse_Webauthn{
- Webauthn: wanlib.CredentialCreationResponseToProto(ccr),
+ Webauthn: wantypes.CredentialCreationResponseToProto(ccr),
},
},
})
@@ -1145,28 +1145,28 @@ func TestSSHOnMultipleNodes(t *testing.T) {
setupUser("leafcluster", "alice", true, leafAuth.GetAuthServer())
setupUser("localhost", "bob", false, rootAuth.GetAuthServer())
- successfulChallenge := func(cluster string) func(ctx context.Context, realOrigin string, assertion *wanlib.CredentialAssertion, prompt wancli.LoginPrompt, _ *wancli.LoginOpts) (*proto.MFAAuthenticateResponse, string, error) {
- return func(ctx context.Context, realOrigin string, assertion *wanlib.CredentialAssertion, prompt wancli.LoginPrompt, _ *wancli.LoginOpts) (*proto.MFAAuthenticateResponse, string, error) {
+ successfulChallenge := func(cluster string) func(ctx context.Context, realOrigin string, assertion *wantypes.CredentialAssertion, prompt wancli.LoginPrompt, _ *wancli.LoginOpts) (*proto.MFAAuthenticateResponse, string, error) {
+ return func(ctx context.Context, realOrigin string, assertion *wantypes.CredentialAssertion, prompt wancli.LoginPrompt, _ *wancli.LoginOpts) (*proto.MFAAuthenticateResponse, string, error) {
car, err := device.SignAssertion(origin(cluster), assertion) // use the fake origin to prevent a mismatch
if err != nil {
return nil, "", err
}
return &proto.MFAAuthenticateResponse{
Response: &proto.MFAAuthenticateResponse_Webauthn{
- Webauthn: wanlib.CredentialAssertionResponseToProto(car),
+ Webauthn: wantypes.CredentialAssertionResponseToProto(car),
},
}, "", nil
}
}
- failedChallenge := func(cluster string) func(ctx context.Context, realOrigin string, assertion *wanlib.CredentialAssertion, prompt wancli.LoginPrompt, _ *wancli.LoginOpts) (*proto.MFAAuthenticateResponse, string, error) {
- return func(ctx context.Context, realOrigin string, assertion *wanlib.CredentialAssertion, prompt wancli.LoginPrompt, _ *wancli.LoginOpts) (*proto.MFAAuthenticateResponse, string, error) {
+ failedChallenge := func(cluster string) func(ctx context.Context, realOrigin string, assertion *wantypes.CredentialAssertion, prompt wancli.LoginPrompt, _ *wancli.LoginOpts) (*proto.MFAAuthenticateResponse, string, error) {
+ return func(ctx context.Context, realOrigin string, assertion *wantypes.CredentialAssertion, prompt wancli.LoginPrompt, _ *wancli.LoginOpts) (*proto.MFAAuthenticateResponse, string, error) {
car, err := device.SignAssertion(origin(cluster), assertion) // use the fake origin to prevent a mismatch
if err != nil {
return nil, "", err
}
- carProto := wanlib.CredentialAssertionResponseToProto(car)
+ carProto := wantypes.CredentialAssertionResponseToProto(car)
carProto.Type = "NOT A VALID TYPE" // set to an invalid type so the ceremony fails
return &proto.MFAAuthenticateResponse{
@@ -1177,7 +1177,7 @@ func TestSSHOnMultipleNodes(t *testing.T) {
}
}
- type mfaPrompt = func(ctx context.Context, origin string, assertion *wanlib.CredentialAssertion, prompt wancli.LoginPrompt, _ *wancli.LoginOpts) (*proto.MFAAuthenticateResponse, string, error)
+ type mfaPrompt = func(ctx context.Context, origin string, assertion *wantypes.CredentialAssertion, prompt wancli.LoginPrompt, _ *wancli.LoginOpts) (*proto.MFAAuthenticateResponse, string, error)
setupChallengeSolver := func(mfaPrompt mfaPrompt) func(t *testing.T) {
return func(t *testing.T) {
inputReader := prompt.NewFakeReader().
diff --git a/tool/tsh/winwebauthn.go b/tool/tsh/webauthnwin.go
similarity index 87%
rename from tool/tsh/winwebauthn.go
rename to tool/tsh/webauthnwin.go
index 24b1c136191d3..7b1f5c261ea81 100644
--- a/tool/tsh/winwebauthn.go
+++ b/tool/tsh/webauthnwin.go
@@ -21,7 +21,7 @@ import (
"github.com/alecthomas/kingpin/v2"
"github.com/gravitational/trace"
- "github.com/gravitational/teleport/lib/auth/webauthnwin"
+ wanwin "github.com/gravitational/teleport/lib/auth/webauthnwin"
)
type webauthnwinCommand struct {
@@ -49,7 +49,7 @@ func newWebauthnwinDiagCommand(app *kingpin.CmdClause) *webauthnwinDiagCommand {
}
func (w *webauthnwinDiagCommand) run(cf *CLIConf) error {
- diag := webauthnwin.CheckSupport()
+ diag := wanwin.CheckSupport()
fmt.Printf("\nWebauthnWin available: %v\n", diag.IsAvailable)
fmt.Printf("Compile support: %v\n", diag.HasCompileSupport)
fmt.Printf("DLL API version: %v\n", diag.WebAuthnAPIVersion)
@@ -59,11 +59,11 @@ func (w *webauthnwinDiagCommand) run(cf *CLIConf) error {
return nil
}
- promptBefore := webauthnwin.PromptWriter
- defer func() { webauthnwin.PromptWriter = promptBefore }()
- webauthnwin.PromptWriter = os.Stderr
+ promptBefore := wanwin.PromptWriter
+ defer func() { wanwin.PromptWriter = promptBefore }()
+ wanwin.PromptWriter = os.Stderr
- resp, err := webauthnwin.Diag(cf.Context)
+ resp, err := wanwin.Diag(cf.Context)
// Abort if we got a nil diagnostic, otherwise print as much as we can.
if resp == nil {
return trace.Wrap(err)