Repository: go-webauthn/webauthn (go)

Issue:
Inconsistent base64 encoding/decoding via JSON
### Version

0.3.1

### Description

The `protocol.CredentialCreation` object returned by `webauthn.BeginRegistration`  uses the `WebauthnID` method from the `webauthn.User` interface to get the Id of the user.

If this object is serialized via the `encoding/json` module, the field gets serialized as base64 via `base64.StdEncoding`.

Later, after registration, if the credential is sent back as part of the login process, it will be decoded as the UserHandle portion of a `AuthenticatorAssertionResponse`, which has the type defined as `URLEncodedBase64`, which defines a custom json marshaller which builds on `base64.RawURLEncoding`.

Since these two base64 encoding aren't compatible, parsing the assertion fails and login can't proceed, specifically generating the error "Parse error for Assertion".

### Reproduction

This issue can be reproduced by registering a new credential, and returning the result of BeginRegistration directly encoded as json.  Finish the registration without changing or parsing the Id on the client side.

Attempt to use the credential without changing the UserHandle field after deserialzing via the standard json encoder.

### Expectations

The expected behavior is that the WebauthnID as returned from the interface method would be able to make a roundtrip in this fashion without needed modification on the server or client side.


### Documentation

Updating the locations that reference `[]byte` to use `URLEncodedBase64` should do it, but there might be backwards compatibility concerns?

https://github.com/go-webauthn/webauthn/blob/83e3622388c50352ecbcc94a0f3ae32cff01de57/webauthn/user.go#L7
https://github.com/go-webauthn/webauthn/blob/83e3622388c50352ecbcc94a0f3ae32cff01de57/protocol/entities.go#L47
https://github.com/go-webauthn/webauthn/blob/83e3622388c50352ecbcc94a0f3ae32cff01de57/protocol/assertion.go#L35
https://github.com/go-webauthn/webauthn/blob/83e3622388c50352ecbcc94a0f3ae32cff01de57/protocol/assertion.go#L65

Pull request:
fix(protocol): user entity id not encoded correctly
This fixes an issue where the protocol.UserEntity field ID was encoded with Base64 URL Encoding with padding instead of without padding.

Fixes #97 

Patch:
diff --git a/protocol/entities.go b/protocol/entities.go
index 5b146ca..cbe829f 100644
--- a/protocol/entities.go
+++ b/protocol/entities.go
@@ -44,5 +44,5 @@ type UserEntity struct {
 	// authentication and authorization decisions MUST be made on the basis of this id
 	// member, not the displayName nor name members. See Section 6.1 of
 	// [RFC8266](https://www.w3.org/TR/webauthn/#biblio-rfc8266).
-	ID []byte `json:"id"`
+	ID URLEncodedBase64 `json:"id"`
 }


Test patch:
diff --git a/protocol/attestation_test.go b/protocol/attestation_test.go
index cfe5e24..2bee34d 100644
--- a/protocol/attestation_test.go
+++ b/protocol/attestation_test.go
@@ -91,7 +91,7 @@ var testAttestationOptions = []string{
 		"user": {
 			"name": "self",
 			"displayName": "self",
-			"id": "2iEAAAAAAAAAAA=="
+			"id": "2iEAAAAAAAAAAA"
 		},
 		"pubKeyCredParams": [
 			{
@@ -116,7 +116,7 @@ var testAttestationOptions = []string{
 		"user": {
 			"name": "flort",
 			"displayName": "flort",
-			"id": "1DMAAAAAAAAAAA=="
+			"id": "1DMAAAAAAAAAAA"
 		},
 		"pubKeyCredParams": [
 			{
@@ -142,7 +142,7 @@ var testAttestationOptions = []string{
 		  "user": {
 			"name": "testuser1",
 			"displayName": "testuser1",
-			"id": "1zMAAAAAAAAAAA=="
+			"id": "1zMAAAAAAAAAAA"
 		  },
 		  "pubKeyCredParams": [
 			{