Fix fido2 login when no pin is set

This commit is contained in:
Bernd Schoolmann 2023-12-31 12:50:20 +01:00
parent 4190167191
commit 476ed11fdd
No known key found for this signature in database
1 changed files with 47 additions and 14 deletions

View File

@ -32,6 +32,9 @@ type Fido2Response struct {
func Fido2TwoFactor(challengeB64 string, credentials []string, config *config.Config) (string, error) { func Fido2TwoFactor(challengeB64 string, credentials []string, config *config.Config) (string, error) {
url, err := url.Parse(config.ConfigFile.ApiUrl) url, err := url.Parse(config.ConfigFile.ApiUrl)
if err != nil {
return "", err
}
rpid := url.Host rpid := url.Host
locs, err := libfido2.DeviceLocations() locs, err := libfido2.DeviceLocations()
@ -52,7 +55,7 @@ func Fido2TwoFactor(challengeB64 string, credentials []string, config *config.Co
for i, cred := range credentials { for i, cred := range credentials {
decodedPublicKey, err := base64.RawURLEncoding.DecodeString(cred) decodedPublicKey, err := base64.RawURLEncoding.DecodeString(cred)
if err != nil { if err != nil {
twofactorLog.Fatal(err.Error()) return "", err
} }
creds[i] = decodedPublicKey creds[i] = decodedPublicKey
} }
@ -61,21 +64,51 @@ func Fido2TwoFactor(challengeB64 string, credentials []string, config *config.Co
clientDataHash := sha256.Sum256([]byte(clientDataJson)) clientDataHash := sha256.Sum256([]byte(clientDataJson))
clientDataJson = base64.URLEncoding.EncodeToString([]byte(clientDataJson)) clientDataJson = base64.URLEncoding.EncodeToString([]byte(clientDataJson))
pin, err := pinentry.GetPassword("Fido2 PIN", "Enter your token's PIN") info, err := device.Info()
if err != nil { if err != nil {
twofactorLog.Fatal(err.Error()) return "", err
}
hasPin := false
for _, option := range info.Options {
if option.Name == "clientPin" && option.Value == "true" {
hasPin = true
}
} }
assertion, err := device.Assertion( var assertion *libfido2.Assertion
rpid, if hasPin {
clientDataHash[:], pin, err := pinentry.GetPassword("Fido2 PIN", "Enter your token's PIN")
creds, if err != nil {
pin, return "", err
&libfido2.AssertionOpts{ }
Extensions: []libfido2.Extension{},
UV: libfido2.False, assertion, err = device.Assertion(
}, rpid,
) clientDataHash[:],
creds,
pin,
&libfido2.AssertionOpts{
Extensions: []libfido2.Extension{},
UV: libfido2.False,
},
)
if err != nil {
return "", err
}
} else {
assertion, err = device.Assertion(
rpid,
clientDataHash[:],
creds,
"",
&libfido2.AssertionOpts{
Extensions: []libfido2.Extension{},
},
)
if err != nil {
return "", err
}
}
authDataRaw := assertion.AuthDataCBOR[2:] // first 2 bytes seem to be from cbor, don't have a proper decoder ATM but this works authDataRaw := assertion.AuthDataCBOR[2:] // first 2 bytes seem to be from cbor, don't have a proper decoder ATM but this works
authData := base64.URLEncoding.EncodeToString(authDataRaw) authData := base64.URLEncoding.EncodeToString(authDataRaw)
@ -101,5 +134,5 @@ func Fido2TwoFactor(challengeB64 string, credentials []string, config *config.Co
} }
respjson, err := json.Marshal(resp) respjson, err := json.Marshal(resp)
return string(respjson), nil return string(respjson), err
} }