From f63fbc1c8eda0faa65bd5cfbbd997d64ac2305ba Mon Sep 17 00:00:00 2001 From: James Elliott Date: Sat, 27 Apr 2024 17:12:48 +1000 Subject: [PATCH] feat!: remove deprecated values (#233) This removes all deprecated fields and functions from the library. BREAKING CHANGE: the following fields and backwards compatible elements have been removed; Icon field from the CredentialEntity struct, WebAuthnIcon function from the User interface, RPIcon/RPOrigin/Timeout fields from the Config struct, Transports field from the CredentialCreationResponse (new field has existed in the AuthenticatorAttestationResponse struct for quite some time which matches the spec). Closes #221 --- protocol/assertion.go | 3 + protocol/attestation.go | 10 ++- protocol/credential.go | 13 ---- protocol/credential_test.go | 124 ------------------------------------ protocol/entities.go | 11 +--- webauthn/registration.go | 2 - webauthn/types.go | 38 ----------- 7 files changed, 12 insertions(+), 189 deletions(-) diff --git a/protocol/assertion.go b/protocol/assertion.go index 184eb42..0b5eaef 100644 --- a/protocol/assertion.go +++ b/protocol/assertion.go @@ -15,6 +15,7 @@ import ( // credential for login/assertion. type CredentialAssertionResponse struct { PublicKeyCredential + AssertionResponse AuthenticatorAssertionResponse `json:"response"` } @@ -22,6 +23,7 @@ type CredentialAssertionResponse struct { // that allows us to verify the client and authenticator data inside the response. type ParsedCredentialAssertionData struct { ParsedPublicKeyCredential + Response ParsedAssertionResponse Raw CredentialAssertionResponse } @@ -30,6 +32,7 @@ type ParsedCredentialAssertionData struct { // ParsedAssertionResponse. type AuthenticatorAssertionResponse struct { AuthenticatorResponse + AuthenticatorData URLEncodedBase64 `json:"authenticatorData"` Signature URLEncodedBase64 `json:"signature"` UserHandle URLEncodedBase64 `json:"userHandle,omitempty"` diff --git a/protocol/attestation.go b/protocol/attestation.go index cdad1bf..36a264a 100644 --- a/protocol/attestation.go +++ b/protocol/attestation.go @@ -22,6 +22,14 @@ type AuthenticatorAttestationResponse struct { // The byte slice of clientDataJSON, which becomes CollectedClientData AuthenticatorResponse + Transports []string `json:"transports,omitempty"` + + AuthenticatorData URLEncodedBase64 `json:"authenticatorData"` + + PublicKey URLEncodedBase64 `json:"publicKey"` + + PublicKeyAlgorithm int64 `json:"publicKeyAlgorithm"` + // AttestationObject is the byte slice version of attestationObject. // This attribute contains an attestation object, which is opaque to, and // cryptographically protected against tampering by, the client. The @@ -33,8 +41,6 @@ type AuthenticatorAttestationResponse struct { // requires to validate the attestation statement, as well as to decode and // validate the authenticator data along with the JSON-serialized client data. AttestationObject URLEncodedBase64 `json:"attestationObject"` - - Transports []string `json:"transports,omitempty"` } // ParsedAttestationResponse is the parsed version of AuthenticatorAttestationResponse. diff --git a/protocol/credential.go b/protocol/credential.go index e316ebb..d532e2b 100644 --- a/protocol/credential.go +++ b/protocol/credential.go @@ -49,12 +49,6 @@ type CredentialCreationResponse struct { PublicKeyCredential AttestationResponse AuthenticatorAttestationResponse `json:"response"` - - // Deprecated: Transports is deprecated due to upstream changes to the API. - // Use the Transports field of AuthenticatorAttestationResponse - // instead. Transports is kept for backward compatibility, and should not - // be used by new clients. - Transports []string `json:"transports,omitempty"` } type ParsedCredentialCreationData struct { @@ -116,13 +110,6 @@ func (ccr CredentialCreationResponse) Parse() (pcc *ParsedCredentialCreationData return nil, ErrParsingData.WithDetails("Error parsing attestation response") } - // TODO: Remove this as it's a backwards compatibility layer. - if len(response.Transports) == 0 && len(ccr.Transports) != 0 { - for _, t := range ccr.Transports { - response.Transports = append(response.Transports, AuthenticatorTransport(t)) - } - } - var attachment AuthenticatorAttachment switch ccr.AuthenticatorAttachment { diff --git a/protocol/credential_test.go b/protocol/credential_test.go index 70f1ba0..26d0256 100644 --- a/protocol/credential_test.go +++ b/protocol/credential_test.go @@ -94,130 +94,6 @@ func TestParseCredentialCreationResponse(t *testing.T) { }, errString: "", }, - { - name: "ShouldParseCredentialRequestDeprecatedTransports", - args: args{ - responseName: "successDeprecatedTransports", - }, - expected: &ParsedCredentialCreationData{ - ParsedPublicKeyCredential: ParsedPublicKeyCredential{ - ParsedCredential: ParsedCredential{ - ID: "6xrtBhJQW6QU4tOaB4rrHaS2Ks0yDDL_q8jDC16DEjZ-VLVf4kCRkvl2xp2D71sTPYns-exsHQHTy3G-zJRK8g", - Type: "public-key", - }, - RawID: byteID, - ClientExtensionResults: AuthenticationExtensionsClientOutputs{ - "appid": true, - }, - }, - Response: ParsedAttestationResponse{ - CollectedClientData: CollectedClientData{ - Type: CeremonyType("webauthn.create"), - Challenge: "W8GzFU8pGjhoRbWrLDlamAfq_y4S1CZG1VuoeRLARrE", - Origin: "https://webauthn.io", - }, - AttestationObject: AttestationObject{ - Format: "none", - RawAuthData: byteAuthData, - AuthData: AuthenticatorData{ - RPIDHash: byteRPIDHash, - Counter: 0, - Flags: 0x041, - AttData: AttestedCredentialData{ - AAGUID: make([]byte, 16), - CredentialID: byteID, - CredentialPublicKey: byteCredentialPubKey, - }, - }, - }, - Transports: []AuthenticatorTransport{USB, NFC, "fake"}, - }, - Raw: CredentialCreationResponse{ - PublicKeyCredential: PublicKeyCredential{ - Credential: Credential{ - Type: "public-key", - ID: "6xrtBhJQW6QU4tOaB4rrHaS2Ks0yDDL_q8jDC16DEjZ-VLVf4kCRkvl2xp2D71sTPYns-exsHQHTy3G-zJRK8g", - }, - RawID: byteID, - ClientExtensionResults: AuthenticationExtensionsClientOutputs{ - "appid": true, - }, - AuthenticatorAttachment: "not-valid", - }, - AttestationResponse: AuthenticatorAttestationResponse{ - AuthenticatorResponse: AuthenticatorResponse{ - ClientDataJSON: byteClientDataJSON, - }, - AttestationObject: byteAttObject, - }, - Transports: []string{"usb", "nfc", "fake"}, - }, - }, - errString: "", - }, - { - name: "ShouldParseCredentialRequestDeprecatedTransportsShouldNotOverride", - args: args{ - responseName: "successDeprecatedTransportsAndNew", - }, - expected: &ParsedCredentialCreationData{ - ParsedPublicKeyCredential: ParsedPublicKeyCredential{ - ParsedCredential: ParsedCredential{ - ID: "6xrtBhJQW6QU4tOaB4rrHaS2Ks0yDDL_q8jDC16DEjZ-VLVf4kCRkvl2xp2D71sTPYns-exsHQHTy3G-zJRK8g", - Type: "public-key", - }, - RawID: byteID, - ClientExtensionResults: AuthenticationExtensionsClientOutputs{ - "appid": true, - }, - AuthenticatorAttachment: CrossPlatform, - }, - Response: ParsedAttestationResponse{ - CollectedClientData: CollectedClientData{ - Type: CeremonyType("webauthn.create"), - Challenge: "W8GzFU8pGjhoRbWrLDlamAfq_y4S1CZG1VuoeRLARrE", - Origin: "https://webauthn.io", - }, - AttestationObject: AttestationObject{ - Format: "none", - RawAuthData: byteAuthData, - AuthData: AuthenticatorData{ - RPIDHash: byteRPIDHash, - Counter: 0, - Flags: 0x041, - AttData: AttestedCredentialData{ - AAGUID: make([]byte, 16), - CredentialID: byteID, - CredentialPublicKey: byteCredentialPubKey, - }, - }, - }, - Transports: []AuthenticatorTransport{USB, NFC}, - }, - Raw: CredentialCreationResponse{ - PublicKeyCredential: PublicKeyCredential{ - Credential: Credential{ - Type: "public-key", - ID: "6xrtBhJQW6QU4tOaB4rrHaS2Ks0yDDL_q8jDC16DEjZ-VLVf4kCRkvl2xp2D71sTPYns-exsHQHTy3G-zJRK8g", - }, - RawID: byteID, - ClientExtensionResults: AuthenticationExtensionsClientOutputs{ - "appid": true, - }, - AuthenticatorAttachment: "cross-platform", - }, - AttestationResponse: AuthenticatorAttestationResponse{ - AuthenticatorResponse: AuthenticatorResponse{ - ClientDataJSON: byteClientDataJSON, - }, - AttestationObject: byteAttObject, - Transports: []string{"usb", "nfc"}, - }, - Transports: []string{"usb", "nfc", "fake"}, - }, - }, - errString: "", - }, { name: "ShouldHandleTrailingData", args: args{ diff --git a/protocol/entities.go b/protocol/entities.go index 40f3c30..b0ba2ad 100644 --- a/protocol/entities.go +++ b/protocol/entities.go @@ -14,16 +14,6 @@ type CredentialEntity struct { // intended only for display, i.e., aiding the user in determining the difference between user accounts with similar // displayNames. For example, "alexm", "alex.p.mueller@example.com" or "+14255551234". Name string `json:"name"` - - // A serialized URL which resolves to an image associated with the entity. For example, - // this could be a user’s avatar or a Relying Party's logo. This URL MUST be an a priori - // authenticated URL. Authenticators MUST accept and store a 128-byte minimum length for - // an icon member’s value. Authenticators MAY ignore an icon member’s value if its length - // is greater than 128 bytes. The URL’s scheme MAY be "data" to avoid fetches of the URL, - // at the cost of needing more storage. - // - // Deprecated: this has been removed from the specification recommendations. - Icon string `json:"icon,omitempty"` } // The RelyingPartyEntity represents the PublicKeyCredentialRpEntity IDL and is used to supply additional Relying Party @@ -32,6 +22,7 @@ type CredentialEntity struct { // Specification: §5.4.2. Relying Party Parameters for Credential Generation (https://www.w3.org/TR/webauthn/#dictionary-rp-credential-params) type RelyingPartyEntity struct { CredentialEntity + // A unique identifier for the Relying Party entity, which sets the RP ID. ID string `json:"id"` } diff --git a/webauthn/registration.go b/webauthn/registration.go index c6009ea..92566bd 100644 --- a/webauthn/registration.go +++ b/webauthn/registration.go @@ -42,7 +42,6 @@ func (webauthn *WebAuthn) BeginRegistration(user User, opts ...RegistrationOptio DisplayName: user.WebAuthnDisplayName(), CredentialEntity: protocol.CredentialEntity{ Name: user.WebAuthnName(), - Icon: user.WebAuthnIcon(), }, } @@ -50,7 +49,6 @@ func (webauthn *WebAuthn) BeginRegistration(user User, opts ...RegistrationOptio ID: webauthn.Config.RPID, CredentialEntity: protocol.CredentialEntity{ Name: webauthn.Config.RPDisplayName, - Icon: webauthn.Config.RPIcon, }, } diff --git a/webauthn/types.go b/webauthn/types.go index 79b6db1..161c45b 100644 --- a/webauthn/types.go +++ b/webauthn/types.go @@ -63,21 +63,6 @@ type Config struct { Timeouts TimeoutsConfig validated bool - - // RPIcon sets the icon URL for the Relying Party Server. - // - // Deprecated: this option has been removed from newer specifications due to security considerations. - RPIcon string - - // RPOrigin configures the permitted Relying Party Server Origin. - // - // Deprecated: Use RPOrigins instead. - RPOrigin string - - // Timeout configures the default timeout in milliseconds. - // - // Deprecated: Use Timeouts instead. - Timeout int } // TimeoutsConfig represents the WebAuthn timeouts configuration. @@ -120,20 +105,9 @@ func (config *Config) validate() error { return fmt.Errorf(errFmtFieldNotValidURI, "RPID", err) } - if config.RPIcon != "" { - if _, err = url.Parse(config.RPIcon); err != nil { - return fmt.Errorf(errFmtFieldNotValidURI, "RPIcon", err) - } - } - defaultTimeoutConfig := defaultTimeout defaultTimeoutUVDConfig := defaultTimeoutUVD - if config.Timeout != 0 { - defaultTimeoutConfig = time.Millisecond * time.Duration(config.Timeout) - defaultTimeoutUVDConfig = defaultTimeoutConfig - } - if config.Timeouts.Login.Timeout.Milliseconds() == 0 { config.Timeouts.Login.Timeout = defaultTimeoutConfig } @@ -150,14 +124,6 @@ func (config *Config) validate() error { config.Timeouts.Registration.TimeoutUVD = defaultTimeoutUVDConfig } - if len(config.RPOrigin) > 0 { - if len(config.RPOrigins) != 0 { - return fmt.Errorf("deprecated field 'RPOrigin' can't be defined at the same tme as the replacement field 'RPOrigins'") - } - - config.RPOrigins = []string{config.RPOrigin} - } - if len(config.RPOrigins) == 0 { return fmt.Errorf("must provide at least one value to the 'RPOrigins' field") } @@ -214,10 +180,6 @@ type User interface { // WebAuthnCredentials provides the list of Credential objects owned by the user. WebAuthnCredentials() []Credential - - // WebAuthnIcon is a deprecated option. - // Deprecated: this has been removed from the specification recommendation. Suggest a blank string. - WebAuthnIcon() string } // SessionData is the data that should be stored by the Relying Party for the duration of the web authentication