Virtual Authenticator
Aplicações web podem habilitar um mecanismo de autenticação baseado em chaves públicas conhecido como Web Authentication para autenticar usuários sem usar uma senha. Web Authentication define APIs que permitem ao usuário criar uma credencial e registra-la com um autenticador. Um autenticador pode ser um dispositivo ou um software que guarde as chaves públicas do usuário e as acesse caso seja pedido.
Como o nome sugere, Virtual Authenticator emula esses autenticadores para testes.
Virtual Authenticator Options
Um Autenticador Virtual tem uma série de propriedades. Essas propriedades são mapeadas como VirtualAuthenticatorOptions nos bindings do Selenium.
public void testVirtualOptions() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setIsUserVerified(true) .setHasUserVerification(true) .setIsUserConsenting(true) .setTransport(VirtualAuthenticatorOptions.Transport.USB) .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java
package dev.selenium.interactions; import dev.selenium.BaseChromeTest; import java.security.spec.PKCS8EncodedKeySpec; import java.util.Base64; import java.util.List; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.openqa.selenium.InvalidArgumentException; import org.openqa.selenium.virtualauthenticator.Credential; import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator; import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator; import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions; public class VirtualAuthenticatorTest extends BaseChromeTest { /** * A pkcs#8 encoded encrypted RSA private key as a base64url string. */ private final static String base64EncodedRsaPK = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB" + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi" + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P" + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui" + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/" + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib" + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko" + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC" + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK" + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63" + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl" + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V" + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B" + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw" + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI" + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB" + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g=="; private final static PKCS8EncodedKeySpec rsaPrivateKey = new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK)); // A pkcs#8 encoded unencrypted EC256 private key as a base64url string. String base64EncodedEC256PK = "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB"; PKCS8EncodedKeySpec ec256PrivateKey = new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK)); @Test public void testVirtualOptions() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setIsUserVerified(true) .setHasUserVerification(true) .setIsUserConsenting(true) .setTransport(VirtualAuthenticatorOptions.Transport.USB) .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .setHasResidentKey(false); Assertions.assertEquals(6, options.toMap().size()); } @Test public void testCreateAuthenticator() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .setHasResidentKey(false); VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options); List<Credential> credentialList = authenticator.getCredentials(); Assertions.assertEquals(0, credentialList.size()); } @Test public void testRemoveAuthenticator() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions(); VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options); ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator); Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials); } @Test public void testCreateAndAddResidentialKey() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2) .setHasResidentKey(true) .setHasUserVerification(true) .setIsUserVerified(true); VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options); byte[] credentialId = {1, 2, 3, 4}; byte[] userHandle = {1}; Credential residentCredential = Credential.createResidentCredential( credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0); authenticator.addCredential(residentCredential); List<Credential> credentialList = authenticator.getCredentials(); Assertions.assertEquals(1, credentialList.size()); Credential credential = credentialList.get(0); Assertions.assertArrayEquals(credentialId, credential.getId()); } @Test public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .setHasResidentKey(true); VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options); PKCS8EncodedKeySpec privateKey = new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK)); byte[] credentialId = {1, 2, 3, 4}; byte[] userHandle = {1}; Credential credential = Credential.createResidentCredential( credentialId, "localhost", privateKey, userHandle, /*signCount=*/0); Assertions.assertThrows(InvalidArgumentException.class, () -> authenticator.addCredential(credential)); } @Test @Disabled("A fix was implemented and will be available in Selenium 4.34.") public void testCreateAndAddNonResidentialKey() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .setHasResidentKey(false); VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options); byte[] credentialId = {1, 2, 3, 4}; Credential nonResidentCredential = Credential.createNonResidentCredential( credentialId, "localhost", ec256PrivateKey, /*signCount=*/0); authenticator.addCredential(nonResidentCredential); List<Credential> credentialList = authenticator.getCredentials(); Assertions.assertEquals(1, credentialList.size()); Credential credential = credentialList.get(0); Assertions.assertArrayEquals(credentialId, credential.getId()); } @Test public void testGetCredential() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2) .setHasResidentKey(true) .setHasUserVerification(true) .setIsUserVerified(true); VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options); byte[] credentialId = {1, 2, 3, 4}; byte[] userHandle = {1}; Credential residentCredential = Credential.createResidentCredential( credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0); authenticator.addCredential(residentCredential); List<Credential> credentialList = authenticator.getCredentials(); Assertions.assertEquals(1, credentialList.size()); Credential credential = credentialList.get(0); Assertions.assertArrayEquals(credentialId, credential.getId()); Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded()); } @Test public void testRemoveCredential() { VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions()); byte[] credentialId = {1, 2, 3, 4}; Credential credential = Credential.createNonResidentCredential( credentialId, "localhost", rsaPrivateKey, 0); authenticator.addCredential(credential); authenticator.removeCredential(credentialId); Assertions.assertEquals(0, authenticator.getCredentials().size()); } @Test public void testRemoveAllCredentials() { VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions()); byte[] credentialId = {1, 2, 3, 4}; Credential residentCredential = Credential.createNonResidentCredential( credentialId, "localhost", rsaPrivateKey, /*signCount=*/0); authenticator.addCredential(residentCredential); authenticator.removeAllCredentials(); Assertions.assertEquals(0, authenticator.getCredentials().size()); } @Test public void testSetUserVerified() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setIsUserVerified(true); Assertions.assertTrue((boolean) options.toMap().get("isUserVerified")); } }
// Create virtual authenticator options VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetIsUserVerified(true) .SetHasUserVerification(true) .SetIsUserConsenting(true) .SetTransport(VirtualAuthenticatorOptions.Transport.USB) .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .SetHasResidentKey(false);
examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs
using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.IdentityModel.Tokens; using OpenQA.Selenium; using OpenQA.Selenium.VirtualAuth; using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions; using System.Collections.Generic; using System; namespace SeleniumDocs.VirtualAuthentication { [TestClass] public class VirtualAuthenticatorTest : BaseChromeTest { //A pkcs#8 encoded encrypted RSA private key as a base64 string. private static string base64EncodedRSAPK = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB" + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi" + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P" + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui" + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/" + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib" + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko" + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC" + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK" + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63" + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl" + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V" + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B" + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw" + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI" + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB" + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g=="; private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK); private string base64EncodedPK = Base64UrlEncoder.Encode(bytes); // A pkcs#8 encoded unencrypted EC256 private key as a base64url string. private string base64EncodedEC256PK = "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB"; [TestMethod] public void VirtualOptionsShouldAllowSettingOptions() { // Create virtual authenticator options VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetIsUserVerified(true) .SetHasUserVerification(true) .SetIsUserConsenting(true) .SetTransport(VirtualAuthenticatorOptions.Transport.USB) .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .SetHasResidentKey(false); Assert.AreEqual(6, options.ToDictionary().Count); } [TestMethod] public void ShouldBeAbleToCreateAuthenticator() { // Create virtual authenticator options VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .SetHasResidentKey(false); // Register a virtual authenticator ((WebDriver)driver).AddVirtualAuthenticator(options); List<Credential> credentialList = ((WebDriver)driver).GetCredentials(); Assert.AreEqual(0, credentialList.Count); } [TestMethod] public void ShouldBeAbleToRemoveAuthenticator() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .SetHasResidentKey(false); String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options); ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId); // Since the authenticator was removed, any operation using it will throw an error Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials()); } [TestMethod] public void ShouldBeAbleToCreateAndAddResidentialKey() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetProtocol(Protocol.CTAP2) .SetHasResidentKey(true) .SetHasUserVerification(true) .SetIsUserVerified(true); ((WebDriver)driver).AddVirtualAuthenticator(options); byte[] credentialId = { 1, 2, 3, 4 }; byte[] userHandle = { 1 }; Credential residentCredential = Credential.CreateResidentCredential( credentialId, "localhost", base64EncodedPK, userHandle, 0); ((WebDriver)driver).AddCredential(residentCredential); List<Credential> credentialList = ((WebDriver)driver).GetCredentials(); Assert.AreEqual(1, credentialList.Count); Credential credential = credentialList[0]; CollectionAssert.AreEqual(credentialId, credential.Id); } [TestMethod] public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .SetHasResidentKey(true); ((WebDriver)driver).AddVirtualAuthenticator(options); byte[] credentialId = { 1, 2, 3, 4 }; byte[] userHandle = { 1 }; Credential credential = Credential.CreateResidentCredential( credentialId, "localhost", base64EncodedEC256PK, userHandle, 0); Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential)); } [TestMethod] public void ShouldBeAbleToCreateAndAddNonResidentKey() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .SetHasResidentKey(false); ((WebDriver)driver).AddVirtualAuthenticator(options); byte[] credentialId = { 1, 2, 3, 4 }; Credential nonResidentCredential = Credential.CreateNonResidentCredential( credentialId, "localhost", base64EncodedEC256PK, 0); ((WebDriver)driver).AddCredential(nonResidentCredential); List<Credential> credentialList = ((WebDriver)driver).GetCredentials(); Assert.AreEqual(1, credentialList.Count); Credential credential = credentialList[0]; CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id); } [TestMethod] public void ShouldBeAbleToGetCredential() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetProtocol(Protocol.CTAP2) .SetHasResidentKey(true) .SetHasUserVerification(true) .SetIsUserVerified(true); ((WebDriver)driver).AddVirtualAuthenticator(options); byte[] credentialId = { 1, 2, 3, 4 }; byte[] userHandle = { 1 }; Credential residentCredential = Credential.CreateResidentCredential( credentialId, "localhost", base64EncodedPK, userHandle, 0); ((WebDriver)driver).AddCredential(residentCredential); List<Credential> credentialList = ((WebDriver)driver).GetCredentials(); Assert.AreEqual(1, credentialList.Count); Credential credential = credentialList[0]; CollectionAssert.AreEqual(credentialId, residentCredential.Id); Assert.AreEqual(base64EncodedPK, credential.PrivateKey); } [TestMethod] public void ShouldBeAbleToRemoveCredential() { ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions()); byte[] credentialId = { 1, 2, 3, 4 }; Credential nonResidentCredential = Credential.CreateNonResidentCredential( credentialId, "localhost", base64EncodedEC256PK, 0); ((WebDriver)driver).AddCredential(nonResidentCredential); ((WebDriver)driver).RemoveCredential(credentialId); Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count); } [TestMethod] public void ShouldBeAbleToRemoveAllCredentias() { ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions()); byte[] credentialId = { 1, 2, 3, 4 }; Credential nonResidentCredential = Credential.CreateNonResidentCredential( credentialId, "localhost", base64EncodedEC256PK, 0); ((WebDriver)driver).AddCredential(nonResidentCredential); ((WebDriver)driver).RemoveAllCredentials(); Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count); } [TestMethod] public void ShouldBeSetVerifiedOption() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetIsUserVerified(true); Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]); } } }
options = VirtualAuthenticatorOptions() options.is_user_verified = True options.has_user_verification = True options.is_user_consenting = True options.transport = VirtualAuthenticatorOptions.Transport.USB options.protocol = VirtualAuthenticatorOptions.Protocol.U2F options.has_resident_key = False
examples/python/tests/interactions/test_virtual_authenticator.py
import pytest from base64 import urlsafe_b64decode, urlsafe_b64encode from selenium.common.exceptions import InvalidArgumentException from selenium.webdriver.chrome.webdriver import WebDriver from selenium.webdriver.common.virtual_authenticator import ( Credential, VirtualAuthenticatorOptions, ) BASE64__ENCODED_PK = ''' MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0 +j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM 8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD /Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ 5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8 K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa 9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H BYGpI8g== ''' @pytest.fixture(scope="module", autouse=True) def driver(): yield WebDriver() def test_virtual_authenticator_options(): options = VirtualAuthenticatorOptions() options.is_user_verified = True options.has_user_verification = True options.is_user_consenting = True options.transport = VirtualAuthenticatorOptions.Transport.USB options.protocol = VirtualAuthenticatorOptions.Protocol.U2F options.has_resident_key = False assert len(options.to_dict()) == 6 def test_add_authenticator(driver): # Create virtual authenticator options options = VirtualAuthenticatorOptions() options.protocol = VirtualAuthenticatorOptions.Protocol.U2F options.has_resident_key = False # Register a virtual authenticator driver.add_virtual_authenticator(options) # Get list of credentials credential_list = driver.get_credentials() assert len(credential_list) == 0 def test_remove_authenticator(driver): # Create default virtual authenticator option options = VirtualAuthenticatorOptions() # Register a virtual authenticator driver.add_virtual_authenticator(options) # Remove virtual authenticator driver.remove_virtual_authenticator() assert driver.virtual_authenticator_id is None def test_create_and_add_resident_key(driver): # Create virtual authenticator options options = VirtualAuthenticatorOptions() options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2 options.has_resident_key = True options.has_user_verification = True options.is_user_verified = True # Register a virtual authenticator driver.add_virtual_authenticator(options) # parameters for Resident Credential credential_id = bytearray({1, 2, 3, 4}) rp_id = "localhost" user_handle = bytearray({1}) privatekey = urlsafe_b64decode(BASE64__ENCODED_PK) sign_count = 0 # create a resident credential using above parameters resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count) # add the credential created to virtual authenticator driver.add_credential(resident_credential) # get list of all the registered credentials credential_list = driver.get_credentials() assert len(credential_list) == 1 def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver): # Create virtual authenticator options options = VirtualAuthenticatorOptions() options.protocol = VirtualAuthenticatorOptions.Protocol.U2F options.has_resident_key = False # Register a virtual authenticator driver.add_virtual_authenticator(options) # parameters for Resident Credential credential_id = bytearray({1, 2, 3, 4}) rp_id = "localhost" user_handle = bytearray({1}) privatekey = urlsafe_b64decode(BASE64__ENCODED_PK) sign_count = 0 # create a resident credential using above parameters credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count) # Expect InvalidArgumentException with pytest.raises(InvalidArgumentException): driver.add_credential(credential) def test_create_and_add_non_resident_key(driver): # Create virtual authenticator options options = VirtualAuthenticatorOptions() options.protocol = VirtualAuthenticatorOptions.Protocol.U2F options.has_resident_key = False # Register a virtual authenticator driver.add_virtual_authenticator(options) # parameters for Non Resident Credential credential_id = bytearray({1, 2, 3, 4}) rp_id = "localhost" privatekey = urlsafe_b64decode(BASE64__ENCODED_PK) sign_count = 0 # create a non resident credential using above parameters credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count) # add the credential created to virtual authenticator driver.add_credential(credential) # get list of all the registered credentials credential_list = driver.get_credentials() assert len(credential_list) == 1 def test_get_credential(driver): # Create virtual authenticator options options = VirtualAuthenticatorOptions() options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2 options.has_resident_key = True options.has_user_verfied = True options.is_user_verified = True # Register a virtual authenticator driver.add_virtual_authenticator(options) # parameters for Resident Credential credential_id = bytearray({1, 2, 3, 4}) rp_id = "localhost" user_handle = bytearray({1}) privatekey = urlsafe_b64decode(BASE64__ENCODED_PK) sign_count = 0 # create a resident credential using above parameters credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count) # add the credential created to virtual authenticator driver.add_credential(credential) # get list of all the registered credentials credential_list = driver.get_credentials() assert len(credential_list) == 1 assert credential_list[0].id == urlsafe_b64encode(credential_id).decode() def test_remove_credential(driver): # Create default virtual authenticator options options = VirtualAuthenticatorOptions() # Register a virtual authenticator driver.add_virtual_authenticator(options) # parameters for Non Resident Credential credential_id = bytearray({1, 2, 3, 4}) rp_id = "localhost" privatekey = urlsafe_b64decode(BASE64__ENCODED_PK) sign_count = 0 # create a non resident credential using above parameters credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count) # add the credential created to virtual authenticator driver.add_credential(credential) # remove the credential created from virtual authenticator driver.remove_credential(credential.id) # credential can also be removed using Byte Array # driver.remove_credential(credential_id) assert len(driver.get_credentials()) == 0 def test_remove_all_credentials(driver): # Create default virtual authenticator options options = VirtualAuthenticatorOptions() options.has_resident_key = True # Register a virtual authenticator driver.add_virtual_authenticator(options) # parameters for Resident Credential credential_id = bytearray({1, 2, 3, 4}) rp_id = "localhost" user_handle = bytearray({1}) privatekey = urlsafe_b64decode(BASE64__ENCODED_PK) sign_count = 0 # create a resident credential using above parameters resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count) # add the credential created to virtual authenticator driver.add_credential(resident_credential) # remove all credentials in virtual authenticator driver.remove_all_credentials() assert len(driver.get_credentials()) == 0 def test_set_user_verified(): # Create virtual authenticator options options = VirtualAuthenticatorOptions() options.is_user_verified = True assert options.to_dict().get("isUserVerified") is True
options.setHasUserVerification(true); options.setIsUserConsenting(true); options.setTransport(Transport['USB']); options.setProtocol(Protocol['U2F']); options.setHasResidentKey(false); assert(Object.keys(options).length === 6);
examples/javascript/test/virtual_authenticator/virtualAuthenticatorOptions.spec.js
const {VirtualAuthenticatorOptions, Transport, Protocol} = require("selenium-webdriver/lib/virtual_authenticator"); const assert = require('assert') describe('Virtual authenticator options', function () { let options; it('Virtual options', async function () { options = new VirtualAuthenticatorOptions(); options.setIsUserVerified(true); options.setHasUserVerification(true); options.setIsUserConsenting(true); options.setTransport(Transport['USB']); options.setProtocol(Protocol['U2F']); options.setHasResidentKey(false); assert(Object.keys(options).length === 6); }); it('User verified', async function () { options.setIsUserVerified(true); assert(options.toDict()['isUserVerified']); }); });
Add Virtual Authenticator
Cria um novo autenticador virtual com as propriedades fornecidas.
public void testCreateAuthenticator() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .setHasResidentKey(false); VirtualAuthenticator authenticator =
examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java
package dev.selenium.interactions; import dev.selenium.BaseChromeTest; import java.security.spec.PKCS8EncodedKeySpec; import java.util.Base64; import java.util.List; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.openqa.selenium.InvalidArgumentException; import org.openqa.selenium.virtualauthenticator.Credential; import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator; import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator; import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions; public class VirtualAuthenticatorTest extends BaseChromeTest { /** * A pkcs#8 encoded encrypted RSA private key as a base64url string. */ private final static String base64EncodedRsaPK = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB" + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi" + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P" + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui" + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/" + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib" + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko" + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC" + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK" + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63" + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl" + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V" + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B" + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw" + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI" + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB" + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g=="; private final static PKCS8EncodedKeySpec rsaPrivateKey = new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK)); // A pkcs#8 encoded unencrypted EC256 private key as a base64url string. String base64EncodedEC256PK = "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB"; PKCS8EncodedKeySpec ec256PrivateKey = new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK)); @Test public void testVirtualOptions() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setIsUserVerified(true) .setHasUserVerification(true) .setIsUserConsenting(true) .setTransport(VirtualAuthenticatorOptions.Transport.USB) .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .setHasResidentKey(false); Assertions.assertEquals(6, options.toMap().size()); } @Test public void testCreateAuthenticator() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .setHasResidentKey(false); VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options); List<Credential> credentialList = authenticator.getCredentials(); Assertions.assertEquals(0, credentialList.size()); } @Test public void testRemoveAuthenticator() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions(); VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options); ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator); Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials); } @Test public void testCreateAndAddResidentialKey() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2) .setHasResidentKey(true) .setHasUserVerification(true) .setIsUserVerified(true); VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options); byte[] credentialId = {1, 2, 3, 4}; byte[] userHandle = {1}; Credential residentCredential = Credential.createResidentCredential( credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0); authenticator.addCredential(residentCredential); List<Credential> credentialList = authenticator.getCredentials(); Assertions.assertEquals(1, credentialList.size()); Credential credential = credentialList.get(0); Assertions.assertArrayEquals(credentialId, credential.getId()); } @Test public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .setHasResidentKey(true); VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options); PKCS8EncodedKeySpec privateKey = new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK)); byte[] credentialId = {1, 2, 3, 4}; byte[] userHandle = {1}; Credential credential = Credential.createResidentCredential( credentialId, "localhost", privateKey, userHandle, /*signCount=*/0); Assertions.assertThrows(InvalidArgumentException.class, () -> authenticator.addCredential(credential)); } @Test @Disabled("A fix was implemented and will be available in Selenium 4.34.") public void testCreateAndAddNonResidentialKey() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .setHasResidentKey(false); VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options); byte[] credentialId = {1, 2, 3, 4}; Credential nonResidentCredential = Credential.createNonResidentCredential( credentialId, "localhost", ec256PrivateKey, /*signCount=*/0); authenticator.addCredential(nonResidentCredential); List<Credential> credentialList = authenticator.getCredentials(); Assertions.assertEquals(1, credentialList.size()); Credential credential = credentialList.get(0); Assertions.assertArrayEquals(credentialId, credential.getId()); } @Test public void testGetCredential() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2) .setHasResidentKey(true) .setHasUserVerification(true) .setIsUserVerified(true); VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options); byte[] credentialId = {1, 2, 3, 4}; byte[] userHandle = {1}; Credential residentCredential = Credential.createResidentCredential( credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0); authenticator.addCredential(residentCredential); List<Credential> credentialList = authenticator.getCredentials(); Assertions.assertEquals(1, credentialList.size()); Credential credential = credentialList.get(0); Assertions.assertArrayEquals(credentialId, credential.getId()); Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded()); } @Test public void testRemoveCredential() { VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions()); byte[] credentialId = {1, 2, 3, 4}; Credential credential = Credential.createNonResidentCredential( credentialId, "localhost", rsaPrivateKey, 0); authenticator.addCredential(credential); authenticator.removeCredential(credentialId); Assertions.assertEquals(0, authenticator.getCredentials().size()); } @Test public void testRemoveAllCredentials() { VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions()); byte[] credentialId = {1, 2, 3, 4}; Credential residentCredential = Credential.createNonResidentCredential( credentialId, "localhost", rsaPrivateKey, /*signCount=*/0); authenticator.addCredential(residentCredential); authenticator.removeAllCredentials(); Assertions.assertEquals(0, authenticator.getCredentials().size()); } @Test public void testSetUserVerified() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setIsUserVerified(true); Assertions.assertTrue((boolean) options.toMap().get("isUserVerified")); } }
// Create virtual authenticator options VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .SetHasResidentKey(false); // Register a virtual authenticator ((WebDriver)driver).AddVirtualAuthenticator(options); List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs
using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.IdentityModel.Tokens; using OpenQA.Selenium; using OpenQA.Selenium.VirtualAuth; using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions; using System.Collections.Generic; using System; namespace SeleniumDocs.VirtualAuthentication { [TestClass] public class VirtualAuthenticatorTest : BaseChromeTest { //A pkcs#8 encoded encrypted RSA private key as a base64 string. private static string base64EncodedRSAPK = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB" + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi" + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P" + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui" + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/" + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib" + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko" + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC" + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK" + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63" + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl" + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V" + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B" + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw" + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI" + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB" + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g=="; private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK); private string base64EncodedPK = Base64UrlEncoder.Encode(bytes); // A pkcs#8 encoded unencrypted EC256 private key as a base64url string. private string base64EncodedEC256PK = "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB"; [TestMethod] public void VirtualOptionsShouldAllowSettingOptions() { // Create virtual authenticator options VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetIsUserVerified(true) .SetHasUserVerification(true) .SetIsUserConsenting(true) .SetTransport(VirtualAuthenticatorOptions.Transport.USB) .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .SetHasResidentKey(false); Assert.AreEqual(6, options.ToDictionary().Count); } [TestMethod] public void ShouldBeAbleToCreateAuthenticator() { // Create virtual authenticator options VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .SetHasResidentKey(false); // Register a virtual authenticator ((WebDriver)driver).AddVirtualAuthenticator(options); List<Credential> credentialList = ((WebDriver)driver).GetCredentials(); Assert.AreEqual(0, credentialList.Count); } [TestMethod] public void ShouldBeAbleToRemoveAuthenticator() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .SetHasResidentKey(false); String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options); ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId); // Since the authenticator was removed, any operation using it will throw an error Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials()); } [TestMethod] public void ShouldBeAbleToCreateAndAddResidentialKey() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetProtocol(Protocol.CTAP2) .SetHasResidentKey(true) .SetHasUserVerification(true) .SetIsUserVerified(true); ((WebDriver)driver).AddVirtualAuthenticator(options); byte[] credentialId = { 1, 2, 3, 4 }; byte[] userHandle = { 1 }; Credential residentCredential = Credential.CreateResidentCredential( credentialId, "localhost", base64EncodedPK, userHandle, 0); ((WebDriver)driver).AddCredential(residentCredential); List<Credential> credentialList = ((WebDriver)driver).GetCredentials(); Assert.AreEqual(1, credentialList.Count); Credential credential = credentialList[0]; CollectionAssert.AreEqual(credentialId, credential.Id); } [TestMethod] public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .SetHasResidentKey(true); ((WebDriver)driver).AddVirtualAuthenticator(options); byte[] credentialId = { 1, 2, 3, 4 }; byte[] userHandle = { 1 }; Credential credential = Credential.CreateResidentCredential( credentialId, "localhost", base64EncodedEC256PK, userHandle, 0); Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential)); } [TestMethod] public void ShouldBeAbleToCreateAndAddNonResidentKey() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .SetHasResidentKey(false); ((WebDriver)driver).AddVirtualAuthenticator(options); byte[] credentialId = { 1, 2, 3, 4 }; Credential nonResidentCredential = Credential.CreateNonResidentCredential( credentialId, "localhost", base64EncodedEC256PK, 0); ((WebDriver)driver).AddCredential(nonResidentCredential); List<Credential> credentialList = ((WebDriver)driver).GetCredentials(); Assert.AreEqual(1, credentialList.Count); Credential credential = credentialList[0]; CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id); } [TestMethod] public void ShouldBeAbleToGetCredential() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetProtocol(Protocol.CTAP2) .SetHasResidentKey(true) .SetHasUserVerification(true) .SetIsUserVerified(true); ((WebDriver)driver).AddVirtualAuthenticator(options); byte[] credentialId = { 1, 2, 3, 4 }; byte[] userHandle = { 1 }; Credential residentCredential = Credential.CreateResidentCredential( credentialId, "localhost", base64EncodedPK, userHandle, 0); ((WebDriver)driver).AddCredential(residentCredential); List<Credential> credentialList = ((WebDriver)driver).GetCredentials(); Assert.AreEqual(1, credentialList.Count); Credential credential = credentialList[0]; CollectionAssert.AreEqual(credentialId, residentCredential.Id); Assert.AreEqual(base64EncodedPK, credential.PrivateKey); } [TestMethod] public void ShouldBeAbleToRemoveCredential() { ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions()); byte[] credentialId = { 1, 2, 3, 4 }; Credential nonResidentCredential = Credential.CreateNonResidentCredential( credentialId, "localhost", base64EncodedEC256PK, 0); ((WebDriver)driver).AddCredential(nonResidentCredential); ((WebDriver)driver).RemoveCredential(credentialId); Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count); } [TestMethod] public void ShouldBeAbleToRemoveAllCredentias() { ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions()); byte[] credentialId = { 1, 2, 3, 4 }; Credential nonResidentCredential = Credential.CreateNonResidentCredential( credentialId, "localhost", base64EncodedEC256PK, 0); ((WebDriver)driver).AddCredential(nonResidentCredential); ((WebDriver)driver).RemoveAllCredentials(); Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count); } [TestMethod] public void ShouldBeSetVerifiedOption() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetIsUserVerified(true); Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]); } } }
options = VirtualAuthenticatorOptions() options.protocol = VirtualAuthenticatorOptions.Protocol.U2F options.has_resident_key = False # Register a virtual authenticator driver.add_virtual_authenticator(options)
examples/python/tests/interactions/test_virtual_authenticator.py
import pytest from base64 import urlsafe_b64decode, urlsafe_b64encode from selenium.common.exceptions import InvalidArgumentException from selenium.webdriver.chrome.webdriver import WebDriver from selenium.webdriver.common.virtual_authenticator import ( Credential, VirtualAuthenticatorOptions, ) BASE64__ENCODED_PK = ''' MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0 +j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM 8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD /Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ 5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8 K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa 9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H BYGpI8g== ''' @pytest.fixture(scope="module", autouse=True) def driver(): yield WebDriver() def test_virtual_authenticator_options(): options = VirtualAuthenticatorOptions() options.is_user_verified = True options.has_user_verification = True options.is_user_consenting = True options.transport = VirtualAuthenticatorOptions.Transport.USB options.protocol = VirtualAuthenticatorOptions.Protocol.U2F options.has_resident_key = False assert len(options.to_dict()) == 6 def test_add_authenticator(driver): # Create virtual authenticator options options = VirtualAuthenticatorOptions() options.protocol = VirtualAuthenticatorOptions.Protocol.U2F options.has_resident_key = False # Register a virtual authenticator driver.add_virtual_authenticator(options) # Get list of credentials credential_list = driver.get_credentials() assert len(credential_list) == 0 def test_remove_authenticator(driver): # Create default virtual authenticator option options = VirtualAuthenticatorOptions() # Register a virtual authenticator driver.add_virtual_authenticator(options) # Remove virtual authenticator driver.remove_virtual_authenticator() assert driver.virtual_authenticator_id is None def test_create_and_add_resident_key(driver): # Create virtual authenticator options options = VirtualAuthenticatorOptions() options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2 options.has_resident_key = True options.has_user_verification = True options.is_user_verified = True # Register a virtual authenticator driver.add_virtual_authenticator(options) # parameters for Resident Credential credential_id = bytearray({1, 2, 3, 4}) rp_id = "localhost" user_handle = bytearray({1}) privatekey = urlsafe_b64decode(BASE64__ENCODED_PK) sign_count = 0 # create a resident credential using above parameters resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count) # add the credential created to virtual authenticator driver.add_credential(resident_credential) # get list of all the registered credentials credential_list = driver.get_credentials() assert len(credential_list) == 1 def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver): # Create virtual authenticator options options = VirtualAuthenticatorOptions() options.protocol = VirtualAuthenticatorOptions.Protocol.U2F options.has_resident_key = False # Register a virtual authenticator driver.add_virtual_authenticator(options) # parameters for Resident Credential credential_id = bytearray({1, 2, 3, 4}) rp_id = "localhost" user_handle = bytearray({1}) privatekey = urlsafe_b64decode(BASE64__ENCODED_PK) sign_count = 0 # create a resident credential using above parameters credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count) # Expect InvalidArgumentException with pytest.raises(InvalidArgumentException): driver.add_credential(credential) def test_create_and_add_non_resident_key(driver): # Create virtual authenticator options options = VirtualAuthenticatorOptions() options.protocol = VirtualAuthenticatorOptions.Protocol.U2F options.has_resident_key = False # Register a virtual authenticator driver.add_virtual_authenticator(options) # parameters for Non Resident Credential credential_id = bytearray({1, 2, 3, 4}) rp_id = "localhost" privatekey = urlsafe_b64decode(BASE64__ENCODED_PK) sign_count = 0 # create a non resident credential using above parameters credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count) # add the credential created to virtual authenticator driver.add_credential(credential) # get list of all the registered credentials credential_list = driver.get_credentials() assert len(credential_list) == 1 def test_get_credential(driver): # Create virtual authenticator options options = VirtualAuthenticatorOptions() options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2 options.has_resident_key = True options.has_user_verfied = True options.is_user_verified = True # Register a virtual authenticator driver.add_virtual_authenticator(options) # parameters for Resident Credential credential_id = bytearray({1, 2, 3, 4}) rp_id = "localhost" user_handle = bytearray({1}) privatekey = urlsafe_b64decode(BASE64__ENCODED_PK) sign_count = 0 # create a resident credential using above parameters credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count) # add the credential created to virtual authenticator driver.add_credential(credential) # get list of all the registered credentials credential_list = driver.get_credentials() assert len(credential_list) == 1 assert credential_list[0].id == urlsafe_b64encode(credential_id).decode() def test_remove_credential(driver): # Create default virtual authenticator options options = VirtualAuthenticatorOptions() # Register a virtual authenticator driver.add_virtual_authenticator(options) # parameters for Non Resident Credential credential_id = bytearray({1, 2, 3, 4}) rp_id = "localhost" privatekey = urlsafe_b64decode(BASE64__ENCODED_PK) sign_count = 0 # create a non resident credential using above parameters credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count) # add the credential created to virtual authenticator driver.add_credential(credential) # remove the credential created from virtual authenticator driver.remove_credential(credential.id) # credential can also be removed using Byte Array # driver.remove_credential(credential_id) assert len(driver.get_credentials()) == 0 def test_remove_all_credentials(driver): # Create default virtual authenticator options options = VirtualAuthenticatorOptions() options.has_resident_key = True # Register a virtual authenticator driver.add_virtual_authenticator(options) # parameters for Resident Credential credential_id = bytearray({1, 2, 3, 4}) rp_id = "localhost" user_handle = bytearray({1}) privatekey = urlsafe_b64decode(BASE64__ENCODED_PK) sign_count = 0 # create a resident credential using above parameters resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count) # add the credential created to virtual authenticator driver.add_credential(resident_credential) # remove all credentials in virtual authenticator driver.remove_all_credentials() assert len(driver.get_credentials()) == 0 def test_set_user_verified(): # Create virtual authenticator options options = VirtualAuthenticatorOptions() options.is_user_verified = True assert options.to_dict().get("isUserVerified") is True
options.setProtocol(Protocol['U2F']); options.setHasResidentKey(false); // Register a virtual authenticator await driver.addVirtualAuthenticator(options);
examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js
const { Builder} = require("selenium-webdriver"); const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator"); const assert = require('assert') const { InvalidArgumentError } = require("selenium-webdriver/lib/error"); describe('Virtual authenticator', function() { const BASE64_ENCODED_PK = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" + "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" + "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" + "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" + "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" + "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" + "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" + "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" + "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" + "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" + "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" + "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" + "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" + "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" + "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" + "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" + "BYGpI8g=="; const base64EncodedPK = "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB"; let options; let driver; before(async function() { options = new VirtualAuthenticatorOptions(); driver = await new Builder().forBrowser('chrome').build(); }); after(async() => await driver.quit()); function arraysEqual(array1, array2) { return (array1.length === array2.length && array1.every((item) => array2.includes(item)) && array2.every((item) => array1.includes(item))); } it('Register a virtual authenticator', async function() { options.setProtocol(Protocol['U2F']); options.setHasResidentKey(false); // Register a virtual authenticator await driver.addVirtualAuthenticator(options); let credentialList = await driver.getCredentials(); assert.equal(0, credentialList.length); }); it('Remove authenticator', async function() { await driver.addVirtualAuthenticator(options); await driver.removeVirtualAuthenticator(); // Since the authenticator was removed, any operation using it will throw an error try { await driver.getCredentials() } catch (e) { if (e instanceof InvalidArgumentError) { assert(true) } else { assert(false) } } }); it('Createa and add residential key', async function() { options.setProtocol(Protocol['CTAP2']); options.setHasResidentKey(true); options.setHasUserVerification(true); options.setIsUserVerified(true); await driver.addVirtualAuthenticator(options); let residentCredential = new Credential().createResidentCredential( new Uint8Array([1, 2, 3, 4]), 'localhost', new Uint8Array([1]), Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'), 0); await driver.addCredential(residentCredential); let credentialList = await driver.getCredentials(); assert.equal(1, credentialList.length); let credential_id = credentialList[0].id(); let test_id = new Uint8Array([1, 2, 3, 4]); assert(arraysEqual(credential_id, test_id)); }); it('Add resident credential not supported when authenticator uses U2F protocol', async function() { options.setProtocol(Protocol['U2F']); options.setHasResidentKey(true); await driver.addVirtualAuthenticator(options); let credential = new Credential().createResidentCredential( new Uint8Array([1, 2, 3, 4]), 'localhost', new Uint8Array([1]), Buffer.from(base64EncodedPK, 'base64').toString('binary'), 0); try { await driver.addCredential(credential) } catch (e) { if (e instanceof InvalidArgumentError) { assert(true) } else { assert(false) } } }); it('Create and add non residential key', async function() { options.setProtocol(Protocol['U2F']); options.setHasResidentKey(false); await driver.addVirtualAuthenticator(options); let nonResidentCredential = new Credential().createNonResidentCredential( new Uint8Array([1, 2, 3, 4]), 'localhost', Buffer.from(base64EncodedPK, 'base64').toString('binary'), 0); await driver.addCredential(nonResidentCredential); let credentialList = await driver.getCredentials(); assert.equal(1, credentialList.length); let credential_id = credentialList[0].id(); let test_id = new Uint8Array([1, 2, 3, 4]); assert(arraysEqual(credential_id, test_id)); }); it('Get credential', async function() { options.setProtocol(Protocol['CTAP2']); options.setHasResidentKey(true); options.setHasUserVerification(true); options.setIsUserVerified(true); await driver.addVirtualAuthenticator(options); let residentCredential = new Credential().createResidentCredential( new Uint8Array([1, 2, 3, 4]), 'localhost', new Uint8Array([1]), Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'), 0); await driver.addCredential(residentCredential); let credentialList = await driver.getCredentials(); assert.equal(1, credentialList.length); let credential_id = credentialList[0].id(); let test_id = new Uint8Array([1, 2, 3, 4]); assert(arraysEqual(credential_id, test_id)); assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64')); }); it('Remove all credentials', async function() { await driver.addVirtualAuthenticator(options); let nonResidentCredential = new Credential().createNonResidentCredential( new Uint8Array([1, 2, 3, 4]), 'localhost', Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'), 0); await driver.addCredential(nonResidentCredential); await driver.removeAllCredentials(); let credentialList = await driver.getCredentials(); assert.equal(0, credentialList.length); }); it('Set is user verified', async function() { options.setIsUserVerified(true); assert.equal(options.getIsUserVerified(), true); }); });
Remove Virtual Authenticator
Remove o autenticador virtual adicionado anteriormente.
examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java
package dev.selenium.interactions; import dev.selenium.BaseChromeTest; import java.security.spec.PKCS8EncodedKeySpec; import java.util.Base64; import java.util.List; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.openqa.selenium.InvalidArgumentException; import org.openqa.selenium.virtualauthenticator.Credential; import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator; import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator; import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions; public class VirtualAuthenticatorTest extends BaseChromeTest { /** * A pkcs#8 encoded encrypted RSA private key as a base64url string. */ private final static String base64EncodedRsaPK = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB" + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi" + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P" + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui" + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/" + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib" + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko" + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC" + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK" + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63" + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl" + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V" + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B" + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw" + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI" + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB" + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g=="; private final static PKCS8EncodedKeySpec rsaPrivateKey = new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK)); // A pkcs#8 encoded unencrypted EC256 private key as a base64url string. String base64EncodedEC256PK = "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB"; PKCS8EncodedKeySpec ec256PrivateKey = new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK)); @Test public void testVirtualOptions() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setIsUserVerified(true) .setHasUserVerification(true) .setIsUserConsenting(true) .setTransport(VirtualAuthenticatorOptions.Transport.USB) .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .setHasResidentKey(false); Assertions.assertEquals(6, options.toMap().size()); } @Test public void testCreateAuthenticator() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .setHasResidentKey(false); VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options); List<Credential> credentialList = authenticator.getCredentials(); Assertions.assertEquals(0, credentialList.size()); } @Test public void testRemoveAuthenticator() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions(); VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options); ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator); Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials); } @Test public void testCreateAndAddResidentialKey() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2) .setHasResidentKey(true) .setHasUserVerification(true) .setIsUserVerified(true); VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options); byte[] credentialId = {1, 2, 3, 4}; byte[] userHandle = {1}; Credential residentCredential = Credential.createResidentCredential( credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0); authenticator.addCredential(residentCredential); List<Credential> credentialList = authenticator.getCredentials(); Assertions.assertEquals(1, credentialList.size()); Credential credential = credentialList.get(0); Assertions.assertArrayEquals(credentialId, credential.getId()); } @Test public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .setHasResidentKey(true); VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options); PKCS8EncodedKeySpec privateKey = new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK)); byte[] credentialId = {1, 2, 3, 4}; byte[] userHandle = {1}; Credential credential = Credential.createResidentCredential( credentialId, "localhost", privateKey, userHandle, /*signCount=*/0); Assertions.assertThrows(InvalidArgumentException.class, () -> authenticator.addCredential(credential)); } @Test @Disabled("A fix was implemented and will be available in Selenium 4.34.") public void testCreateAndAddNonResidentialKey() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .setHasResidentKey(false); VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options); byte[] credentialId = {1, 2, 3, 4}; Credential nonResidentCredential = Credential.createNonResidentCredential( credentialId, "localhost", ec256PrivateKey, /*signCount=*/0); authenticator.addCredential(nonResidentCredential); List<Credential> credentialList = authenticator.getCredentials(); Assertions.assertEquals(1, credentialList.size()); Credential credential = credentialList.get(0); Assertions.assertArrayEquals(credentialId, credential.getId()); } @Test public void testGetCredential() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2) .setHasResidentKey(true) .setHasUserVerification(true) .setIsUserVerified(true); VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options); byte[] credentialId = {1, 2, 3, 4}; byte[] userHandle = {1}; Credential residentCredential = Credential.createResidentCredential( credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0); authenticator.addCredential(residentCredential); List<Credential> credentialList = authenticator.getCredentials(); Assertions.assertEquals(1, credentialList.size()); Credential credential = credentialList.get(0); Assertions.assertArrayEquals(credentialId, credential.getId()); Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded()); } @Test public void testRemoveCredential() { VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions()); byte[] credentialId = {1, 2, 3, 4}; Credential credential = Credential.createNonResidentCredential( credentialId, "localhost", rsaPrivateKey, 0); authenticator.addCredential(credential); authenticator.removeCredential(credentialId); Assertions.assertEquals(0, authenticator.getCredentials().size()); } @Test public void testRemoveAllCredentials() { VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions()); byte[] credentialId = {1, 2, 3, 4}; Credential residentCredential = Credential.createNonResidentCredential( credentialId, "localhost", rsaPrivateKey, /*signCount=*/0); authenticator.addCredential(residentCredential); authenticator.removeAllCredentials(); Assertions.assertEquals(0, authenticator.getCredentials().size()); } @Test public void testSetUserVerified() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setIsUserVerified(true); Assertions.assertTrue((boolean) options.toMap().get("isUserVerified")); } }
VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .SetHasResidentKey(false); String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options); ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);
examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs
using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.IdentityModel.Tokens; using OpenQA.Selenium; using OpenQA.Selenium.VirtualAuth; using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions; using System.Collections.Generic; using System; namespace SeleniumDocs.VirtualAuthentication { [TestClass] public class VirtualAuthenticatorTest : BaseChromeTest { //A pkcs#8 encoded encrypted RSA private key as a base64 string. private static string base64EncodedRSAPK = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB" + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi" + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P" + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui" + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/" + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib" + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko" + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC" + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK" + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63" + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl" + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V" + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B" + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw" + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI" + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB" + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g=="; private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK); private string base64EncodedPK = Base64UrlEncoder.Encode(bytes); // A pkcs#8 encoded unencrypted EC256 private key as a base64url string. private string base64EncodedEC256PK = "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB"; [TestMethod] public void VirtualOptionsShouldAllowSettingOptions() { // Create virtual authenticator options VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetIsUserVerified(true) .SetHasUserVerification(true) .SetIsUserConsenting(true) .SetTransport(VirtualAuthenticatorOptions.Transport.USB) .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .SetHasResidentKey(false); Assert.AreEqual(6, options.ToDictionary().Count); } [TestMethod] public void ShouldBeAbleToCreateAuthenticator() { // Create virtual authenticator options VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .SetHasResidentKey(false); // Register a virtual authenticator ((WebDriver)driver).AddVirtualAuthenticator(options); List<Credential> credentialList = ((WebDriver)driver).GetCredentials(); Assert.AreEqual(0, credentialList.Count); } [TestMethod] public void ShouldBeAbleToRemoveAuthenticator() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .SetHasResidentKey(false); String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options); ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId); // Since the authenticator was removed, any operation using it will throw an error Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials()); } [TestMethod] public void ShouldBeAbleToCreateAndAddResidentialKey() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetProtocol(Protocol.CTAP2) .SetHasResidentKey(true) .SetHasUserVerification(true) .SetIsUserVerified(true); ((WebDriver)driver).AddVirtualAuthenticator(options); byte[] credentialId = { 1, 2, 3, 4 }; byte[] userHandle = { 1 }; Credential residentCredential = Credential.CreateResidentCredential( credentialId, "localhost", base64EncodedPK, userHandle, 0); ((WebDriver)driver).AddCredential(residentCredential); List<Credential> credentialList = ((WebDriver)driver).GetCredentials(); Assert.AreEqual(1, credentialList.Count); Credential credential = credentialList[0]; CollectionAssert.AreEqual(credentialId, credential.Id); } [TestMethod] public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .SetHasResidentKey(true); ((WebDriver)driver).AddVirtualAuthenticator(options); byte[] credentialId = { 1, 2, 3, 4 }; byte[] userHandle = { 1 }; Credential credential = Credential.CreateResidentCredential( credentialId, "localhost", base64EncodedEC256PK, userHandle, 0); Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential)); } [TestMethod] public void ShouldBeAbleToCreateAndAddNonResidentKey() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .SetHasResidentKey(false); ((WebDriver)driver).AddVirtualAuthenticator(options); byte[] credentialId = { 1, 2, 3, 4 }; Credential nonResidentCredential = Credential.CreateNonResidentCredential( credentialId, "localhost", base64EncodedEC256PK, 0); ((WebDriver)driver).AddCredential(nonResidentCredential); List<Credential> credentialList = ((WebDriver)driver).GetCredentials(); Assert.AreEqual(1, credentialList.Count); Credential credential = credentialList[0]; CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id); } [TestMethod] public void ShouldBeAbleToGetCredential() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetProtocol(Protocol.CTAP2) .SetHasResidentKey(true) .SetHasUserVerification(true) .SetIsUserVerified(true); ((WebDriver)driver).AddVirtualAuthenticator(options); byte[] credentialId = { 1, 2, 3, 4 }; byte[] userHandle = { 1 }; Credential residentCredential = Credential.CreateResidentCredential( credentialId, "localhost", base64EncodedPK, userHandle, 0); ((WebDriver)driver).AddCredential(residentCredential); List<Credential> credentialList = ((WebDriver)driver).GetCredentials(); Assert.AreEqual(1, credentialList.Count); Credential credential = credentialList[0]; CollectionAssert.AreEqual(credentialId, residentCredential.Id); Assert.AreEqual(base64EncodedPK, credential.PrivateKey); } [TestMethod] public void ShouldBeAbleToRemoveCredential() { ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions()); byte[] credentialId = { 1, 2, 3, 4 }; Credential nonResidentCredential = Credential.CreateNonResidentCredential( credentialId, "localhost", base64EncodedEC256PK, 0); ((WebDriver)driver).AddCredential(nonResidentCredential); ((WebDriver)driver).RemoveCredential(credentialId); Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count); } [TestMethod] public void ShouldBeAbleToRemoveAllCredentias() { ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions()); byte[] credentialId = { 1, 2, 3, 4 }; Credential nonResidentCredential = Credential.CreateNonResidentCredential( credentialId, "localhost", base64EncodedEC256PK, 0); ((WebDriver)driver).AddCredential(nonResidentCredential); ((WebDriver)driver).RemoveAllCredentials(); Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count); } [TestMethod] public void ShouldBeSetVerifiedOption() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetIsUserVerified(true); Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]); } } }
options = VirtualAuthenticatorOptions() # Register a virtual authenticator driver.add_virtual_authenticator(options) # Remove virtual authenticator driver.remove_virtual_authenticator()
examples/python/tests/interactions/test_virtual_authenticator.py
import pytest from base64 import urlsafe_b64decode, urlsafe_b64encode from selenium.common.exceptions import InvalidArgumentException from selenium.webdriver.chrome.webdriver import WebDriver from selenium.webdriver.common.virtual_authenticator import ( Credential, VirtualAuthenticatorOptions, ) BASE64__ENCODED_PK = ''' MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0 +j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM 8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD /Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ 5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8 K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa 9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H BYGpI8g== ''' @pytest.fixture(scope="module", autouse=True) def driver(): yield WebDriver() def test_virtual_authenticator_options(): options = VirtualAuthenticatorOptions() options.is_user_verified = True options.has_user_verification = True options.is_user_consenting = True options.transport = VirtualAuthenticatorOptions.Transport.USB options.protocol = VirtualAuthenticatorOptions.Protocol.U2F options.has_resident_key = False assert len(options.to_dict()) == 6 def test_add_authenticator(driver): # Create virtual authenticator options options = VirtualAuthenticatorOptions() options.protocol = VirtualAuthenticatorOptions.Protocol.U2F options.has_resident_key = False # Register a virtual authenticator driver.add_virtual_authenticator(options) # Get list of credentials credential_list = driver.get_credentials() assert len(credential_list) == 0 def test_remove_authenticator(driver): # Create default virtual authenticator option options = VirtualAuthenticatorOptions() # Register a virtual authenticator driver.add_virtual_authenticator(options) # Remove virtual authenticator driver.remove_virtual_authenticator() assert driver.virtual_authenticator_id is None def test_create_and_add_resident_key(driver): # Create virtual authenticator options options = VirtualAuthenticatorOptions() options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2 options.has_resident_key = True options.has_user_verification = True options.is_user_verified = True # Register a virtual authenticator driver.add_virtual_authenticator(options) # parameters for Resident Credential credential_id = bytearray({1, 2, 3, 4}) rp_id = "localhost" user_handle = bytearray({1}) privatekey = urlsafe_b64decode(BASE64__ENCODED_PK) sign_count = 0 # create a resident credential using above parameters resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count) # add the credential created to virtual authenticator driver.add_credential(resident_credential) # get list of all the registered credentials credential_list = driver.get_credentials() assert len(credential_list) == 1 def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver): # Create virtual authenticator options options = VirtualAuthenticatorOptions() options.protocol = VirtualAuthenticatorOptions.Protocol.U2F options.has_resident_key = False # Register a virtual authenticator driver.add_virtual_authenticator(options) # parameters for Resident Credential credential_id = bytearray({1, 2, 3, 4}) rp_id = "localhost" user_handle = bytearray({1}) privatekey = urlsafe_b64decode(BASE64__ENCODED_PK) sign_count = 0 # create a resident credential using above parameters credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count) # Expect InvalidArgumentException with pytest.raises(InvalidArgumentException): driver.add_credential(credential) def test_create_and_add_non_resident_key(driver): # Create virtual authenticator options options = VirtualAuthenticatorOptions() options.protocol = VirtualAuthenticatorOptions.Protocol.U2F options.has_resident_key = False # Register a virtual authenticator driver.add_virtual_authenticator(options) # parameters for Non Resident Credential credential_id = bytearray({1, 2, 3, 4}) rp_id = "localhost" privatekey = urlsafe_b64decode(BASE64__ENCODED_PK) sign_count = 0 # create a non resident credential using above parameters credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count) # add the credential created to virtual authenticator driver.add_credential(credential) # get list of all the registered credentials credential_list = driver.get_credentials() assert len(credential_list) == 1 def test_get_credential(driver): # Create virtual authenticator options options = VirtualAuthenticatorOptions() options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2 options.has_resident_key = True options.has_user_verfied = True options.is_user_verified = True # Register a virtual authenticator driver.add_virtual_authenticator(options) # parameters for Resident Credential credential_id = bytearray({1, 2, 3, 4}) rp_id = "localhost" user_handle = bytearray({1}) privatekey = urlsafe_b64decode(BASE64__ENCODED_PK) sign_count = 0 # create a resident credential using above parameters credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count) # add the credential created to virtual authenticator driver.add_credential(credential) # get list of all the registered credentials credential_list = driver.get_credentials() assert len(credential_list) == 1 assert credential_list[0].id == urlsafe_b64encode(credential_id).decode() def test_remove_credential(driver): # Create default virtual authenticator options options = VirtualAuthenticatorOptions() # Register a virtual authenticator driver.add_virtual_authenticator(options) # parameters for Non Resident Credential credential_id = bytearray({1, 2, 3, 4}) rp_id = "localhost" privatekey = urlsafe_b64decode(BASE64__ENCODED_PK) sign_count = 0 # create a non resident credential using above parameters credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count) # add the credential created to virtual authenticator driver.add_credential(credential) # remove the credential created from virtual authenticator driver.remove_credential(credential.id) # credential can also be removed using Byte Array # driver.remove_credential(credential_id) assert len(driver.get_credentials()) == 0 def test_remove_all_credentials(driver): # Create default virtual authenticator options options = VirtualAuthenticatorOptions() options.has_resident_key = True # Register a virtual authenticator driver.add_virtual_authenticator(options) # parameters for Resident Credential credential_id = bytearray({1, 2, 3, 4}) rp_id = "localhost" user_handle = bytearray({1}) privatekey = urlsafe_b64decode(BASE64__ENCODED_PK) sign_count = 0 # create a resident credential using above parameters resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count) # add the credential created to virtual authenticator driver.add_credential(resident_credential) # remove all credentials in virtual authenticator driver.remove_all_credentials() assert len(driver.get_credentials()) == 0 def test_set_user_verified(): # Create virtual authenticator options options = VirtualAuthenticatorOptions() options.is_user_verified = True assert options.to_dict().get("isUserVerified") is True
await driver.addVirtualAuthenticator(options); await driver.removeVirtualAuthenticator();
examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js
const { Builder} = require("selenium-webdriver"); const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator"); const assert = require('assert') const { InvalidArgumentError } = require("selenium-webdriver/lib/error"); describe('Virtual authenticator', function() { const BASE64_ENCODED_PK = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" + "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" + "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" + "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" + "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" + "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" + "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" + "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" + "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" + "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" + "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" + "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" + "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" + "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" + "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" + "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" + "BYGpI8g=="; const base64EncodedPK = "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB"; let options; let driver; before(async function() { options = new VirtualAuthenticatorOptions(); driver = await new Builder().forBrowser('chrome').build(); }); after(async() => await driver.quit()); function arraysEqual(array1, array2) { return (array1.length === array2.length && array1.every((item) => array2.includes(item)) && array2.every((item) => array1.includes(item))); } it('Register a virtual authenticator', async function() { options.setProtocol(Protocol['U2F']); options.setHasResidentKey(false); // Register a virtual authenticator await driver.addVirtualAuthenticator(options); let credentialList = await driver.getCredentials(); assert.equal(0, credentialList.length); }); it('Remove authenticator', async function() { await driver.addVirtualAuthenticator(options); await driver.removeVirtualAuthenticator(); // Since the authenticator was removed, any operation using it will throw an error try { await driver.getCredentials() } catch (e) { if (e instanceof InvalidArgumentError) { assert(true) } else { assert(false) } } }); it('Createa and add residential key', async function() { options.setProtocol(Protocol['CTAP2']); options.setHasResidentKey(true); options.setHasUserVerification(true); options.setIsUserVerified(true); await driver.addVirtualAuthenticator(options); let residentCredential = new Credential().createResidentCredential( new Uint8Array([1, 2, 3, 4]), 'localhost', new Uint8Array([1]), Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'), 0); await driver.addCredential(residentCredential); let credentialList = await driver.getCredentials(); assert.equal(1, credentialList.length); let credential_id = credentialList[0].id(); let test_id = new Uint8Array([1, 2, 3, 4]); assert(arraysEqual(credential_id, test_id)); }); it('Add resident credential not supported when authenticator uses U2F protocol', async function() { options.setProtocol(Protocol['U2F']); options.setHasResidentKey(true); await driver.addVirtualAuthenticator(options); let credential = new Credential().createResidentCredential( new Uint8Array([1, 2, 3, 4]), 'localhost', new Uint8Array([1]), Buffer.from(base64EncodedPK, 'base64').toString('binary'), 0); try { await driver.addCredential(credential) } catch (e) { if (e instanceof InvalidArgumentError) { assert(true) } else { assert(false) } } }); it('Create and add non residential key', async function() { options.setProtocol(Protocol['U2F']); options.setHasResidentKey(false); await driver.addVirtualAuthenticator(options); let nonResidentCredential = new Credential().createNonResidentCredential( new Uint8Array([1, 2, 3, 4]), 'localhost', Buffer.from(base64EncodedPK, 'base64').toString('binary'), 0); await driver.addCredential(nonResidentCredential); let credentialList = await driver.getCredentials(); assert.equal(1, credentialList.length); let credential_id = credentialList[0].id(); let test_id = new Uint8Array([1, 2, 3, 4]); assert(arraysEqual(credential_id, test_id)); }); it('Get credential', async function() { options.setProtocol(Protocol['CTAP2']); options.setHasResidentKey(true); options.setHasUserVerification(true); options.setIsUserVerified(true); await driver.addVirtualAuthenticator(options); let residentCredential = new Credential().createResidentCredential( new Uint8Array([1, 2, 3, 4]), 'localhost', new Uint8Array([1]), Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'), 0); await driver.addCredential(residentCredential); let credentialList = await driver.getCredentials(); assert.equal(1, credentialList.length); let credential_id = credentialList[0].id(); let test_id = new Uint8Array([1, 2, 3, 4]); assert(arraysEqual(credential_id, test_id)); assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64')); }); it('Remove all credentials', async function() { await driver.addVirtualAuthenticator(options); let nonResidentCredential = new Credential().createNonResidentCredential( new Uint8Array([1, 2, 3, 4]), 'localhost', Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'), 0); await driver.addCredential(nonResidentCredential); await driver.removeAllCredentials(); let credentialList = await driver.getCredentials(); assert.equal(0, credentialList.length); }); it('Set is user verified', async function() { options.setIsUserVerified(true); assert.equal(options.getIsUserVerified(), true); }); });
Create Resident Credential
Cria uma resident (stateful) credential com os requeridos parâmetros.
byte[] credentialId = {1, 2, 3, 4}; byte[] userHandle = {1}; Credential residentCredential = Credential.createResidentCredential(
examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java
package dev.selenium.interactions; import dev.selenium.BaseChromeTest; import java.security.spec.PKCS8EncodedKeySpec; import java.util.Base64; import java.util.List; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.openqa.selenium.InvalidArgumentException; import org.openqa.selenium.virtualauthenticator.Credential; import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator; import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator; import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions; public class VirtualAuthenticatorTest extends BaseChromeTest { /** * A pkcs#8 encoded encrypted RSA private key as a base64url string. */ private final static String base64EncodedRsaPK = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB" + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi" + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P" + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui" + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/" + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib" + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko" + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC" + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK" + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63" + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl" + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V" + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B" + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw" + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI" + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB" + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g=="; private final static PKCS8EncodedKeySpec rsaPrivateKey = new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK)); // A pkcs#8 encoded unencrypted EC256 private key as a base64url string. String base64EncodedEC256PK = "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB"; PKCS8EncodedKeySpec ec256PrivateKey = new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK)); @Test public void testVirtualOptions() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setIsUserVerified(true) .setHasUserVerification(true) .setIsUserConsenting(true) .setTransport(VirtualAuthenticatorOptions.Transport.USB) .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .setHasResidentKey(false); Assertions.assertEquals(6, options.toMap().size()); } @Test public void testCreateAuthenticator() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .setHasResidentKey(false); VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options); List<Credential> credentialList = authenticator.getCredentials(); Assertions.assertEquals(0, credentialList.size()); } @Test public void testRemoveAuthenticator() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions(); VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options); ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator); Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials); } @Test public void testCreateAndAddResidentialKey() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2) .setHasResidentKey(true) .setHasUserVerification(true) .setIsUserVerified(true); VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options); byte[] credentialId = {1, 2, 3, 4}; byte[] userHandle = {1}; Credential residentCredential = Credential.createResidentCredential( credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0); authenticator.addCredential(residentCredential); List<Credential> credentialList = authenticator.getCredentials(); Assertions.assertEquals(1, credentialList.size()); Credential credential = credentialList.get(0); Assertions.assertArrayEquals(credentialId, credential.getId()); } @Test public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .setHasResidentKey(true); VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options); PKCS8EncodedKeySpec privateKey = new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK)); byte[] credentialId = {1, 2, 3, 4}; byte[] userHandle = {1}; Credential credential = Credential.createResidentCredential( credentialId, "localhost", privateKey, userHandle, /*signCount=*/0); Assertions.assertThrows(InvalidArgumentException.class, () -> authenticator.addCredential(credential)); } @Test @Disabled("A fix was implemented and will be available in Selenium 4.34.") public void testCreateAndAddNonResidentialKey() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .setHasResidentKey(false); VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options); byte[] credentialId = {1, 2, 3, 4}; Credential nonResidentCredential = Credential.createNonResidentCredential( credentialId, "localhost", ec256PrivateKey, /*signCount=*/0); authenticator.addCredential(nonResidentCredential); List<Credential> credentialList = authenticator.getCredentials(); Assertions.assertEquals(1, credentialList.size()); Credential credential = credentialList.get(0); Assertions.assertArrayEquals(credentialId, credential.getId()); } @Test public void testGetCredential() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2) .setHasResidentKey(true) .setHasUserVerification(true) .setIsUserVerified(true); VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options); byte[] credentialId = {1, 2, 3, 4}; byte[] userHandle = {1}; Credential residentCredential = Credential.createResidentCredential( credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0); authenticator.addCredential(residentCredential); List<Credential> credentialList = authenticator.getCredentials(); Assertions.assertEquals(1, credentialList.size()); Credential credential = credentialList.get(0); Assertions.assertArrayEquals(credentialId, credential.getId()); Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded()); } @Test public void testRemoveCredential() { VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions()); byte[] credentialId = {1, 2, 3, 4}; Credential credential = Credential.createNonResidentCredential( credentialId, "localhost", rsaPrivateKey, 0); authenticator.addCredential(credential); authenticator.removeCredential(credentialId); Assertions.assertEquals(0, authenticator.getCredentials().size()); } @Test public void testRemoveAllCredentials() { VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions()); byte[] credentialId = {1, 2, 3, 4}; Credential residentCredential = Credential.createNonResidentCredential( credentialId, "localhost", rsaPrivateKey, /*signCount=*/0); authenticator.addCredential(residentCredential); authenticator.removeAllCredentials(); Assertions.assertEquals(0, authenticator.getCredentials().size()); } @Test public void testSetUserVerified() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setIsUserVerified(true); Assertions.assertTrue((boolean) options.toMap().get("isUserVerified")); } }
byte[] credentialId = { 1, 2, 3, 4 }; byte[] userHandle = { 1 }; Credential residentCredential = Credential.CreateResidentCredential( credentialId, "localhost", base64EncodedPK, userHandle, 0);
examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs
using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.IdentityModel.Tokens; using OpenQA.Selenium; using OpenQA.Selenium.VirtualAuth; using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions; using System.Collections.Generic; using System; namespace SeleniumDocs.VirtualAuthentication { [TestClass] public class VirtualAuthenticatorTest : BaseChromeTest { //A pkcs#8 encoded encrypted RSA private key as a base64 string. private static string base64EncodedRSAPK = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB" + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi" + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P" + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui" + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/" + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib" + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko" + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC" + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK" + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63" + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl" + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V" + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B" + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw" + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI" + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB" + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g=="; private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK); private string base64EncodedPK = Base64UrlEncoder.Encode(bytes); // A pkcs#8 encoded unencrypted EC256 private key as a base64url string. private string base64EncodedEC256PK = "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB"; [TestMethod] public void VirtualOptionsShouldAllowSettingOptions() { // Create virtual authenticator options VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetIsUserVerified(true) .SetHasUserVerification(true) .SetIsUserConsenting(true) .SetTransport(VirtualAuthenticatorOptions.Transport.USB) .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .SetHasResidentKey(false); Assert.AreEqual(6, options.ToDictionary().Count); } [TestMethod] public void ShouldBeAbleToCreateAuthenticator() { // Create virtual authenticator options VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .SetHasResidentKey(false); // Register a virtual authenticator ((WebDriver)driver).AddVirtualAuthenticator(options); List<Credential> credentialList = ((WebDriver)driver).GetCredentials(); Assert.AreEqual(0, credentialList.Count); } [TestMethod] public void ShouldBeAbleToRemoveAuthenticator() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .SetHasResidentKey(false); String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options); ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId); // Since the authenticator was removed, any operation using it will throw an error Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials()); } [TestMethod] public void ShouldBeAbleToCreateAndAddResidentialKey() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetProtocol(Protocol.CTAP2) .SetHasResidentKey(true) .SetHasUserVerification(true) .SetIsUserVerified(true); ((WebDriver)driver).AddVirtualAuthenticator(options); byte[] credentialId = { 1, 2, 3, 4 }; byte[] userHandle = { 1 }; Credential residentCredential = Credential.CreateResidentCredential( credentialId, "localhost", base64EncodedPK, userHandle, 0); ((WebDriver)driver).AddCredential(residentCredential); List<Credential> credentialList = ((WebDriver)driver).GetCredentials(); Assert.AreEqual(1, credentialList.Count); Credential credential = credentialList[0]; CollectionAssert.AreEqual(credentialId, credential.Id); } [TestMethod] public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .SetHasResidentKey(true); ((WebDriver)driver).AddVirtualAuthenticator(options); byte[] credentialId = { 1, 2, 3, 4 }; byte[] userHandle = { 1 }; Credential credential = Credential.CreateResidentCredential( credentialId, "localhost", base64EncodedEC256PK, userHandle, 0); Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential)); } [TestMethod] public void ShouldBeAbleToCreateAndAddNonResidentKey() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .SetHasResidentKey(false); ((WebDriver)driver).AddVirtualAuthenticator(options); byte[] credentialId = { 1, 2, 3, 4 }; Credential nonResidentCredential = Credential.CreateNonResidentCredential( credentialId, "localhost", base64EncodedEC256PK, 0); ((WebDriver)driver).AddCredential(nonResidentCredential); List<Credential> credentialList = ((WebDriver)driver).GetCredentials(); Assert.AreEqual(1, credentialList.Count); Credential credential = credentialList[0]; CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id); } [TestMethod] public void ShouldBeAbleToGetCredential() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetProtocol(Protocol.CTAP2) .SetHasResidentKey(true) .SetHasUserVerification(true) .SetIsUserVerified(true); ((WebDriver)driver).AddVirtualAuthenticator(options); byte[] credentialId = { 1, 2, 3, 4 }; byte[] userHandle = { 1 }; Credential residentCredential = Credential.CreateResidentCredential( credentialId, "localhost", base64EncodedPK, userHandle, 0); ((WebDriver)driver).AddCredential(residentCredential); List<Credential> credentialList = ((WebDriver)driver).GetCredentials(); Assert.AreEqual(1, credentialList.Count); Credential credential = credentialList[0]; CollectionAssert.AreEqual(credentialId, residentCredential.Id); Assert.AreEqual(base64EncodedPK, credential.PrivateKey); } [TestMethod] public void ShouldBeAbleToRemoveCredential() { ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions()); byte[] credentialId = { 1, 2, 3, 4 }; Credential nonResidentCredential = Credential.CreateNonResidentCredential( credentialId, "localhost", base64EncodedEC256PK, 0); ((WebDriver)driver).AddCredential(nonResidentCredential); ((WebDriver)driver).RemoveCredential(credentialId); Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count); } [TestMethod] public void ShouldBeAbleToRemoveAllCredentias() { ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions()); byte[] credentialId = { 1, 2, 3, 4 }; Credential nonResidentCredential = Credential.CreateNonResidentCredential( credentialId, "localhost", base64EncodedEC256PK, 0); ((WebDriver)driver).AddCredential(nonResidentCredential); ((WebDriver)driver).RemoveAllCredentials(); Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count); } [TestMethod] public void ShouldBeSetVerifiedOption() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetIsUserVerified(true); Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]); } } }
# parameters for Resident Credential credential_id = bytearray({1, 2, 3, 4}) rp_id = "localhost" user_handle = bytearray({1}) privatekey = urlsafe_b64decode(BASE64__ENCODED_PK) sign_count = 0 # create a resident credential using above parameters resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
examples/python/tests/interactions/test_virtual_authenticator.py
import pytest from base64 import urlsafe_b64decode, urlsafe_b64encode from selenium.common.exceptions import InvalidArgumentException from selenium.webdriver.chrome.webdriver import WebDriver from selenium.webdriver.common.virtual_authenticator import ( Credential, VirtualAuthenticatorOptions, ) BASE64__ENCODED_PK = ''' MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0 +j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM 8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD /Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ 5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8 K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa 9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H BYGpI8g== ''' @pytest.fixture(scope="module", autouse=True) def driver(): yield WebDriver() def test_virtual_authenticator_options(): options = VirtualAuthenticatorOptions() options.is_user_verified = True options.has_user_verification = True options.is_user_consenting = True options.transport = VirtualAuthenticatorOptions.Transport.USB options.protocol = VirtualAuthenticatorOptions.Protocol.U2F options.has_resident_key = False assert len(options.to_dict()) == 6 def test_add_authenticator(driver): # Create virtual authenticator options options = VirtualAuthenticatorOptions() options.protocol = VirtualAuthenticatorOptions.Protocol.U2F options.has_resident_key = False # Register a virtual authenticator driver.add_virtual_authenticator(options) # Get list of credentials credential_list = driver.get_credentials() assert len(credential_list) == 0 def test_remove_authenticator(driver): # Create default virtual authenticator option options = VirtualAuthenticatorOptions() # Register a virtual authenticator driver.add_virtual_authenticator(options) # Remove virtual authenticator driver.remove_virtual_authenticator() assert driver.virtual_authenticator_id is None def test_create_and_add_resident_key(driver): # Create virtual authenticator options options = VirtualAuthenticatorOptions() options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2 options.has_resident_key = True options.has_user_verification = True options.is_user_verified = True # Register a virtual authenticator driver.add_virtual_authenticator(options) # parameters for Resident Credential credential_id = bytearray({1, 2, 3, 4}) rp_id = "localhost" user_handle = bytearray({1}) privatekey = urlsafe_b64decode(BASE64__ENCODED_PK) sign_count = 0 # create a resident credential using above parameters resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count) # add the credential created to virtual authenticator driver.add_credential(resident_credential) # get list of all the registered credentials credential_list = driver.get_credentials() assert len(credential_list) == 1 def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver): # Create virtual authenticator options options = VirtualAuthenticatorOptions() options.protocol = VirtualAuthenticatorOptions.Protocol.U2F options.has_resident_key = False # Register a virtual authenticator driver.add_virtual_authenticator(options) # parameters for Resident Credential credential_id = bytearray({1, 2, 3, 4}) rp_id = "localhost" user_handle = bytearray({1}) privatekey = urlsafe_b64decode(BASE64__ENCODED_PK) sign_count = 0 # create a resident credential using above parameters credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count) # Expect InvalidArgumentException with pytest.raises(InvalidArgumentException): driver.add_credential(credential) def test_create_and_add_non_resident_key(driver): # Create virtual authenticator options options = VirtualAuthenticatorOptions() options.protocol = VirtualAuthenticatorOptions.Protocol.U2F options.has_resident_key = False # Register a virtual authenticator driver.add_virtual_authenticator(options) # parameters for Non Resident Credential credential_id = bytearray({1, 2, 3, 4}) rp_id = "localhost" privatekey = urlsafe_b64decode(BASE64__ENCODED_PK) sign_count = 0 # create a non resident credential using above parameters credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count) # add the credential created to virtual authenticator driver.add_credential(credential) # get list of all the registered credentials credential_list = driver.get_credentials() assert len(credential_list) == 1 def test_get_credential(driver): # Create virtual authenticator options options = VirtualAuthenticatorOptions() options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2 options.has_resident_key = True options.has_user_verfied = True options.is_user_verified = True # Register a virtual authenticator driver.add_virtual_authenticator(options) # parameters for Resident Credential credential_id = bytearray({1, 2, 3, 4}) rp_id = "localhost" user_handle = bytearray({1}) privatekey = urlsafe_b64decode(BASE64__ENCODED_PK) sign_count = 0 # create a resident credential using above parameters credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count) # add the credential created to virtual authenticator driver.add_credential(credential) # get list of all the registered credentials credential_list = driver.get_credentials() assert len(credential_list) == 1 assert credential_list[0].id == urlsafe_b64encode(credential_id).decode() def test_remove_credential(driver): # Create default virtual authenticator options options = VirtualAuthenticatorOptions() # Register a virtual authenticator driver.add_virtual_authenticator(options) # parameters for Non Resident Credential credential_id = bytearray({1, 2, 3, 4}) rp_id = "localhost" privatekey = urlsafe_b64decode(BASE64__ENCODED_PK) sign_count = 0 # create a non resident credential using above parameters credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count) # add the credential created to virtual authenticator driver.add_credential(credential) # remove the credential created from virtual authenticator driver.remove_credential(credential.id) # credential can also be removed using Byte Array # driver.remove_credential(credential_id) assert len(driver.get_credentials()) == 0 def test_remove_all_credentials(driver): # Create default virtual authenticator options options = VirtualAuthenticatorOptions() options.has_resident_key = True # Register a virtual authenticator driver.add_virtual_authenticator(options) # parameters for Resident Credential credential_id = bytearray({1, 2, 3, 4}) rp_id = "localhost" user_handle = bytearray({1}) privatekey = urlsafe_b64decode(BASE64__ENCODED_PK) sign_count = 0 # create a resident credential using above parameters resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count) # add the credential created to virtual authenticator driver.add_credential(resident_credential) # remove all credentials in virtual authenticator driver.remove_all_credentials() assert len(driver.get_credentials()) == 0 def test_set_user_verified(): # Create virtual authenticator options options = VirtualAuthenticatorOptions() options.is_user_verified = True assert options.to_dict().get("isUserVerified") is True
options.setProtocol(Protocol['CTAP2']); options.setHasResidentKey(true); options.setHasUserVerification(true); options.setIsUserVerified(true); await driver.addVirtualAuthenticator(options); let residentCredential = new Credential().createResidentCredential( new Uint8Array([1, 2, 3, 4]), 'localhost', new Uint8Array([1]), Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'), 0); await driver.addCredential(residentCredential);
examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js
const { Builder} = require("selenium-webdriver"); const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator"); const assert = require('assert') const { InvalidArgumentError } = require("selenium-webdriver/lib/error"); describe('Virtual authenticator', function() { const BASE64_ENCODED_PK = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" + "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" + "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" + "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" + "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" + "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" + "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" + "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" + "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" + "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" + "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" + "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" + "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" + "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" + "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" + "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" + "BYGpI8g=="; const base64EncodedPK = "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB"; let options; let driver; before(async function() { options = new VirtualAuthenticatorOptions(); driver = await new Builder().forBrowser('chrome').build(); }); after(async() => await driver.quit()); function arraysEqual(array1, array2) { return (array1.length === array2.length && array1.every((item) => array2.includes(item)) && array2.every((item) => array1.includes(item))); } it('Register a virtual authenticator', async function() { options.setProtocol(Protocol['U2F']); options.setHasResidentKey(false); // Register a virtual authenticator await driver.addVirtualAuthenticator(options); let credentialList = await driver.getCredentials(); assert.equal(0, credentialList.length); }); it('Remove authenticator', async function() { await driver.addVirtualAuthenticator(options); await driver.removeVirtualAuthenticator(); // Since the authenticator was removed, any operation using it will throw an error try { await driver.getCredentials() } catch (e) { if (e instanceof InvalidArgumentError) { assert(true) } else { assert(false) } } }); it('Createa and add residential key', async function() { options.setProtocol(Protocol['CTAP2']); options.setHasResidentKey(true); options.setHasUserVerification(true); options.setIsUserVerified(true); await driver.addVirtualAuthenticator(options); let residentCredential = new Credential().createResidentCredential( new Uint8Array([1, 2, 3, 4]), 'localhost', new Uint8Array([1]), Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'), 0); await driver.addCredential(residentCredential); let credentialList = await driver.getCredentials(); assert.equal(1, credentialList.length); let credential_id = credentialList[0].id(); let test_id = new Uint8Array([1, 2, 3, 4]); assert(arraysEqual(credential_id, test_id)); }); it('Add resident credential not supported when authenticator uses U2F protocol', async function() { options.setProtocol(Protocol['U2F']); options.setHasResidentKey(true); await driver.addVirtualAuthenticator(options); let credential = new Credential().createResidentCredential( new Uint8Array([1, 2, 3, 4]), 'localhost', new Uint8Array([1]), Buffer.from(base64EncodedPK, 'base64').toString('binary'), 0); try { await driver.addCredential(credential) } catch (e) { if (e instanceof InvalidArgumentError) { assert(true) } else { assert(false) } } }); it('Create and add non residential key', async function() { options.setProtocol(Protocol['U2F']); options.setHasResidentKey(false); await driver.addVirtualAuthenticator(options); let nonResidentCredential = new Credential().createNonResidentCredential( new Uint8Array([1, 2, 3, 4]), 'localhost', Buffer.from(base64EncodedPK, 'base64').toString('binary'), 0); await driver.addCredential(nonResidentCredential); let credentialList = await driver.getCredentials(); assert.equal(1, credentialList.length); let credential_id = credentialList[0].id(); let test_id = new Uint8Array([1, 2, 3, 4]); assert(arraysEqual(credential_id, test_id)); }); it('Get credential', async function() { options.setProtocol(Protocol['CTAP2']); options.setHasResidentKey(true); options.setHasUserVerification(true); options.setIsUserVerified(true); await driver.addVirtualAuthenticator(options); let residentCredential = new Credential().createResidentCredential( new Uint8Array([1, 2, 3, 4]), 'localhost', new Uint8Array([1]), Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'), 0); await driver.addCredential(residentCredential); let credentialList = await driver.getCredentials(); assert.equal(1, credentialList.length); let credential_id = credentialList[0].id(); let test_id = new Uint8Array([1, 2, 3, 4]); assert(arraysEqual(credential_id, test_id)); assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64')); }); it('Remove all credentials', async function() { await driver.addVirtualAuthenticator(options); let nonResidentCredential = new Credential().createNonResidentCredential( new Uint8Array([1, 2, 3, 4]), 'localhost', Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'), 0); await driver.addCredential(nonResidentCredential); await driver.removeAllCredentials(); let credentialList = await driver.getCredentials(); assert.equal(0, credentialList.length); }); it('Set is user verified', async function() { options.setIsUserVerified(true); assert.equal(options.getIsUserVerified(), true); }); });
Create Non-Resident Credential
Cria uma resident (stateless) credential com os requeridos parâmetros.
VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options); byte[] credentialId = {1, 2, 3, 4};
examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java
package dev.selenium.interactions; import dev.selenium.BaseChromeTest; import java.security.spec.PKCS8EncodedKeySpec; import java.util.Base64; import java.util.List; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.openqa.selenium.InvalidArgumentException; import org.openqa.selenium.virtualauthenticator.Credential; import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator; import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator; import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions; public class VirtualAuthenticatorTest extends BaseChromeTest { /** * A pkcs#8 encoded encrypted RSA private key as a base64url string. */ private final static String base64EncodedRsaPK = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB" + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi" + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P" + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui" + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/" + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib" + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko" + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC" + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK" + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63" + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl" + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V" + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B" + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw" + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI" + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB" + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g=="; private final static PKCS8EncodedKeySpec rsaPrivateKey = new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK)); // A pkcs#8 encoded unencrypted EC256 private key as a base64url string. String base64EncodedEC256PK = "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB"; PKCS8EncodedKeySpec ec256PrivateKey = new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK)); @Test public void testVirtualOptions() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setIsUserVerified(true) .setHasUserVerification(true) .setIsUserConsenting(true) .setTransport(VirtualAuthenticatorOptions.Transport.USB) .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .setHasResidentKey(false); Assertions.assertEquals(6, options.toMap().size()); } @Test public void testCreateAuthenticator() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .setHasResidentKey(false); VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options); List<Credential> credentialList = authenticator.getCredentials(); Assertions.assertEquals(0, credentialList.size()); } @Test public void testRemoveAuthenticator() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions(); VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options); ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator); Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials); } @Test public void testCreateAndAddResidentialKey() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2) .setHasResidentKey(true) .setHasUserVerification(true) .setIsUserVerified(true); VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options); byte[] credentialId = {1, 2, 3, 4}; byte[] userHandle = {1}; Credential residentCredential = Credential.createResidentCredential( credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0); authenticator.addCredential(residentCredential); List<Credential> credentialList = authenticator.getCredentials(); Assertions.assertEquals(1, credentialList.size()); Credential credential = credentialList.get(0); Assertions.assertArrayEquals(credentialId, credential.getId()); } @Test public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .setHasResidentKey(true); VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options); PKCS8EncodedKeySpec privateKey = new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK)); byte[] credentialId = {1, 2, 3, 4}; byte[] userHandle = {1}; Credential credential = Credential.createResidentCredential( credentialId, "localhost", privateKey, userHandle, /*signCount=*/0); Assertions.assertThrows(InvalidArgumentException.class, () -> authenticator.addCredential(credential)); } @Test @Disabled("A fix was implemented and will be available in Selenium 4.34.") public void testCreateAndAddNonResidentialKey() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .setHasResidentKey(false); VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options); byte[] credentialId = {1, 2, 3, 4}; Credential nonResidentCredential = Credential.createNonResidentCredential( credentialId, "localhost", ec256PrivateKey, /*signCount=*/0); authenticator.addCredential(nonResidentCredential); List<Credential> credentialList = authenticator.getCredentials(); Assertions.assertEquals(1, credentialList.size()); Credential credential = credentialList.get(0); Assertions.assertArrayEquals(credentialId, credential.getId()); } @Test public void testGetCredential() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2) .setHasResidentKey(true) .setHasUserVerification(true) .setIsUserVerified(true); VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options); byte[] credentialId = {1, 2, 3, 4}; byte[] userHandle = {1}; Credential residentCredential = Credential.createResidentCredential( credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0); authenticator.addCredential(residentCredential); List<Credential> credentialList = authenticator.getCredentials(); Assertions.assertEquals(1, credentialList.size()); Credential credential = credentialList.get(0); Assertions.assertArrayEquals(credentialId, credential.getId()); Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded()); } @Test public void testRemoveCredential() { VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions()); byte[] credentialId = {1, 2, 3, 4}; Credential credential = Credential.createNonResidentCredential( credentialId, "localhost", rsaPrivateKey, 0); authenticator.addCredential(credential); authenticator.removeCredential(credentialId); Assertions.assertEquals(0, authenticator.getCredentials().size()); } @Test public void testRemoveAllCredentials() { VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions()); byte[] credentialId = {1, 2, 3, 4}; Credential residentCredential = Credential.createNonResidentCredential( credentialId, "localhost", rsaPrivateKey, /*signCount=*/0); authenticator.addCredential(residentCredential); authenticator.removeAllCredentials(); Assertions.assertEquals(0, authenticator.getCredentials().size()); } @Test public void testSetUserVerified() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setIsUserVerified(true); Assertions.assertTrue((boolean) options.toMap().get("isUserVerified")); } }
byte[] credentialId = { 1, 2, 3, 4 }; Credential nonResidentCredential = Credential.CreateNonResidentCredential( credentialId, "localhost", base64EncodedEC256PK, 0);
examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs
using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.IdentityModel.Tokens; using OpenQA.Selenium; using OpenQA.Selenium.VirtualAuth; using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions; using System.Collections.Generic; using System; namespace SeleniumDocs.VirtualAuthentication { [TestClass] public class VirtualAuthenticatorTest : BaseChromeTest { //A pkcs#8 encoded encrypted RSA private key as a base64 string. private static string base64EncodedRSAPK = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB" + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi" + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P" + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui" + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/" + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib" + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko" + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC" + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK" + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63" + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl" + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V" + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B" + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw" + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI" + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB" + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g=="; private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK); private string base64EncodedPK = Base64UrlEncoder.Encode(bytes); // A pkcs#8 encoded unencrypted EC256 private key as a base64url string. private string base64EncodedEC256PK = "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB"; [TestMethod] public void VirtualOptionsShouldAllowSettingOptions() { // Create virtual authenticator options VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetIsUserVerified(true) .SetHasUserVerification(true) .SetIsUserConsenting(true) .SetTransport(VirtualAuthenticatorOptions.Transport.USB) .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .SetHasResidentKey(false); Assert.AreEqual(6, options.ToDictionary().Count); } [TestMethod] public void ShouldBeAbleToCreateAuthenticator() { // Create virtual authenticator options VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .SetHasResidentKey(false); // Register a virtual authenticator ((WebDriver)driver).AddVirtualAuthenticator(options); List<Credential> credentialList = ((WebDriver)driver).GetCredentials(); Assert.AreEqual(0, credentialList.Count); } [TestMethod] public void ShouldBeAbleToRemoveAuthenticator() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .SetHasResidentKey(false); String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options); ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId); // Since the authenticator was removed, any operation using it will throw an error Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials()); } [TestMethod] public void ShouldBeAbleToCreateAndAddResidentialKey() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetProtocol(Protocol.CTAP2) .SetHasResidentKey(true) .SetHasUserVerification(true) .SetIsUserVerified(true); ((WebDriver)driver).AddVirtualAuthenticator(options); byte[] credentialId = { 1, 2, 3, 4 }; byte[] userHandle = { 1 }; Credential residentCredential = Credential.CreateResidentCredential( credentialId, "localhost", base64EncodedPK, userHandle, 0); ((WebDriver)driver).AddCredential(residentCredential); List<Credential> credentialList = ((WebDriver)driver).GetCredentials(); Assert.AreEqual(1, credentialList.Count); Credential credential = credentialList[0]; CollectionAssert.AreEqual(credentialId, credential.Id); } [TestMethod] public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .SetHasResidentKey(true); ((WebDriver)driver).AddVirtualAuthenticator(options); byte[] credentialId = { 1, 2, 3, 4 }; byte[] userHandle = { 1 }; Credential credential = Credential.CreateResidentCredential( credentialId, "localhost", base64EncodedEC256PK, userHandle, 0); Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential)); } [TestMethod] public void ShouldBeAbleToCreateAndAddNonResidentKey() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .SetHasResidentKey(false); ((WebDriver)driver).AddVirtualAuthenticator(options); byte[] credentialId = { 1, 2, 3, 4 }; Credential nonResidentCredential = Credential.CreateNonResidentCredential( credentialId, "localhost", base64EncodedEC256PK, 0); ((WebDriver)driver).AddCredential(nonResidentCredential); List<Credential> credentialList = ((WebDriver)driver).GetCredentials(); Assert.AreEqual(1, credentialList.Count); Credential credential = credentialList[0]; CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id); } [TestMethod] public void ShouldBeAbleToGetCredential() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetProtocol(Protocol.CTAP2) .SetHasResidentKey(true) .SetHasUserVerification(true) .SetIsUserVerified(true); ((WebDriver)driver).AddVirtualAuthenticator(options); byte[] credentialId = { 1, 2, 3, 4 }; byte[] userHandle = { 1 }; Credential residentCredential = Credential.CreateResidentCredential( credentialId, "localhost", base64EncodedPK, userHandle, 0); ((WebDriver)driver).AddCredential(residentCredential); List<Credential> credentialList = ((WebDriver)driver).GetCredentials(); Assert.AreEqual(1, credentialList.Count); Credential credential = credentialList[0]; CollectionAssert.AreEqual(credentialId, residentCredential.Id); Assert.AreEqual(base64EncodedPK, credential.PrivateKey); } [TestMethod] public void ShouldBeAbleToRemoveCredential() { ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions()); byte[] credentialId = { 1, 2, 3, 4 }; Credential nonResidentCredential = Credential.CreateNonResidentCredential( credentialId, "localhost", base64EncodedEC256PK, 0); ((WebDriver)driver).AddCredential(nonResidentCredential); ((WebDriver)driver).RemoveCredential(credentialId); Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count); } [TestMethod] public void ShouldBeAbleToRemoveAllCredentias() { ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions()); byte[] credentialId = { 1, 2, 3, 4 }; Credential nonResidentCredential = Credential.CreateNonResidentCredential( credentialId, "localhost", base64EncodedEC256PK, 0); ((WebDriver)driver).AddCredential(nonResidentCredential); ((WebDriver)driver).RemoveAllCredentials(); Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count); } [TestMethod] public void ShouldBeSetVerifiedOption() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetIsUserVerified(true); Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]); } } }
# parameters for Non Resident Credential credential_id = bytearray({1, 2, 3, 4}) rp_id = "localhost" privatekey = urlsafe_b64decode(BASE64__ENCODED_PK) sign_count = 0 # create a non resident credential using above parameters credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)
examples/python/tests/interactions/test_virtual_authenticator.py
import pytest from base64 import urlsafe_b64decode, urlsafe_b64encode from selenium.common.exceptions import InvalidArgumentException from selenium.webdriver.chrome.webdriver import WebDriver from selenium.webdriver.common.virtual_authenticator import ( Credential, VirtualAuthenticatorOptions, ) BASE64__ENCODED_PK = ''' MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0 +j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM 8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD /Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ 5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8 K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa 9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H BYGpI8g== ''' @pytest.fixture(scope="module", autouse=True) def driver(): yield WebDriver() def test_virtual_authenticator_options(): options = VirtualAuthenticatorOptions() options.is_user_verified = True options.has_user_verification = True options.is_user_consenting = True options.transport = VirtualAuthenticatorOptions.Transport.USB options.protocol = VirtualAuthenticatorOptions.Protocol.U2F options.has_resident_key = False assert len(options.to_dict()) == 6 def test_add_authenticator(driver): # Create virtual authenticator options options = VirtualAuthenticatorOptions() options.protocol = VirtualAuthenticatorOptions.Protocol.U2F options.has_resident_key = False # Register a virtual authenticator driver.add_virtual_authenticator(options) # Get list of credentials credential_list = driver.get_credentials() assert len(credential_list) == 0 def test_remove_authenticator(driver): # Create default virtual authenticator option options = VirtualAuthenticatorOptions() # Register a virtual authenticator driver.add_virtual_authenticator(options) # Remove virtual authenticator driver.remove_virtual_authenticator() assert driver.virtual_authenticator_id is None def test_create_and_add_resident_key(driver): # Create virtual authenticator options options = VirtualAuthenticatorOptions() options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2 options.has_resident_key = True options.has_user_verification = True options.is_user_verified = True # Register a virtual authenticator driver.add_virtual_authenticator(options) # parameters for Resident Credential credential_id = bytearray({1, 2, 3, 4}) rp_id = "localhost" user_handle = bytearray({1}) privatekey = urlsafe_b64decode(BASE64__ENCODED_PK) sign_count = 0 # create a resident credential using above parameters resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count) # add the credential created to virtual authenticator driver.add_credential(resident_credential) # get list of all the registered credentials credential_list = driver.get_credentials() assert len(credential_list) == 1 def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver): # Create virtual authenticator options options = VirtualAuthenticatorOptions() options.protocol = VirtualAuthenticatorOptions.Protocol.U2F options.has_resident_key = False # Register a virtual authenticator driver.add_virtual_authenticator(options) # parameters for Resident Credential credential_id = bytearray({1, 2, 3, 4}) rp_id = "localhost" user_handle = bytearray({1}) privatekey = urlsafe_b64decode(BASE64__ENCODED_PK) sign_count = 0 # create a resident credential using above parameters credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count) # Expect InvalidArgumentException with pytest.raises(InvalidArgumentException): driver.add_credential(credential) def test_create_and_add_non_resident_key(driver): # Create virtual authenticator options options = VirtualAuthenticatorOptions() options.protocol = VirtualAuthenticatorOptions.Protocol.U2F options.has_resident_key = False # Register a virtual authenticator driver.add_virtual_authenticator(options) # parameters for Non Resident Credential credential_id = bytearray({1, 2, 3, 4}) rp_id = "localhost" privatekey = urlsafe_b64decode(BASE64__ENCODED_PK) sign_count = 0 # create a non resident credential using above parameters credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count) # add the credential created to virtual authenticator driver.add_credential(credential) # get list of all the registered credentials credential_list = driver.get_credentials() assert len(credential_list) == 1 def test_get_credential(driver): # Create virtual authenticator options options = VirtualAuthenticatorOptions() options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2 options.has_resident_key = True options.has_user_verfied = True options.is_user_verified = True # Register a virtual authenticator driver.add_virtual_authenticator(options) # parameters for Resident Credential credential_id = bytearray({1, 2, 3, 4}) rp_id = "localhost" user_handle = bytearray({1}) privatekey = urlsafe_b64decode(BASE64__ENCODED_PK) sign_count = 0 # create a resident credential using above parameters credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count) # add the credential created to virtual authenticator driver.add_credential(credential) # get list of all the registered credentials credential_list = driver.get_credentials() assert len(credential_list) == 1 assert credential_list[0].id == urlsafe_b64encode(credential_id).decode() def test_remove_credential(driver): # Create default virtual authenticator options options = VirtualAuthenticatorOptions() # Register a virtual authenticator driver.add_virtual_authenticator(options) # parameters for Non Resident Credential credential_id = bytearray({1, 2, 3, 4}) rp_id = "localhost" privatekey = urlsafe_b64decode(BASE64__ENCODED_PK) sign_count = 0 # create a non resident credential using above parameters credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count) # add the credential created to virtual authenticator driver.add_credential(credential) # remove the credential created from virtual authenticator driver.remove_credential(credential.id) # credential can also be removed using Byte Array # driver.remove_credential(credential_id) assert len(driver.get_credentials()) == 0 def test_remove_all_credentials(driver): # Create default virtual authenticator options options = VirtualAuthenticatorOptions() options.has_resident_key = True # Register a virtual authenticator driver.add_virtual_authenticator(options) # parameters for Resident Credential credential_id = bytearray({1, 2, 3, 4}) rp_id = "localhost" user_handle = bytearray({1}) privatekey = urlsafe_b64decode(BASE64__ENCODED_PK) sign_count = 0 # create a resident credential using above parameters resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count) # add the credential created to virtual authenticator driver.add_credential(resident_credential) # remove all credentials in virtual authenticator driver.remove_all_credentials() assert len(driver.get_credentials()) == 0 def test_set_user_verified(): # Create virtual authenticator options options = VirtualAuthenticatorOptions() options.is_user_verified = True assert options.to_dict().get("isUserVerified") is True
let nonResidentCredential = new Credential().createNonResidentCredential( new Uint8Array([1, 2, 3, 4]), 'localhost', Buffer.from(base64EncodedPK, 'base64').toString('binary'), 0);
examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js
const { Builder} = require("selenium-webdriver"); const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator"); const assert = require('assert') const { InvalidArgumentError } = require("selenium-webdriver/lib/error"); describe('Virtual authenticator', function() { const BASE64_ENCODED_PK = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" + "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" + "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" + "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" + "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" + "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" + "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" + "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" + "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" + "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" + "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" + "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" + "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" + "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" + "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" + "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" + "BYGpI8g=="; const base64EncodedPK = "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB"; let options; let driver; before(async function() { options = new VirtualAuthenticatorOptions(); driver = await new Builder().forBrowser('chrome').build(); }); after(async() => await driver.quit()); function arraysEqual(array1, array2) { return (array1.length === array2.length && array1.every((item) => array2.includes(item)) && array2.every((item) => array1.includes(item))); } it('Register a virtual authenticator', async function() { options.setProtocol(Protocol['U2F']); options.setHasResidentKey(false); // Register a virtual authenticator await driver.addVirtualAuthenticator(options); let credentialList = await driver.getCredentials(); assert.equal(0, credentialList.length); }); it('Remove authenticator', async function() { await driver.addVirtualAuthenticator(options); await driver.removeVirtualAuthenticator(); // Since the authenticator was removed, any operation using it will throw an error try { await driver.getCredentials() } catch (e) { if (e instanceof InvalidArgumentError) { assert(true) } else { assert(false) } } }); it('Createa and add residential key', async function() { options.setProtocol(Protocol['CTAP2']); options.setHasResidentKey(true); options.setHasUserVerification(true); options.setIsUserVerified(true); await driver.addVirtualAuthenticator(options); let residentCredential = new Credential().createResidentCredential( new Uint8Array([1, 2, 3, 4]), 'localhost', new Uint8Array([1]), Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'), 0); await driver.addCredential(residentCredential); let credentialList = await driver.getCredentials(); assert.equal(1, credentialList.length); let credential_id = credentialList[0].id(); let test_id = new Uint8Array([1, 2, 3, 4]); assert(arraysEqual(credential_id, test_id)); }); it('Add resident credential not supported when authenticator uses U2F protocol', async function() { options.setProtocol(Protocol['U2F']); options.setHasResidentKey(true); await driver.addVirtualAuthenticator(options); let credential = new Credential().createResidentCredential( new Uint8Array([1, 2, 3, 4]), 'localhost', new Uint8Array([1]), Buffer.from(base64EncodedPK, 'base64').toString('binary'), 0); try { await driver.addCredential(credential) } catch (e) { if (e instanceof InvalidArgumentError) { assert(true) } else { assert(false) } } }); it('Create and add non residential key', async function() { options.setProtocol(Protocol['U2F']); options.setHasResidentKey(false); await driver.addVirtualAuthenticator(options); let nonResidentCredential = new Credential().createNonResidentCredential( new Uint8Array([1, 2, 3, 4]), 'localhost', Buffer.from(base64EncodedPK, 'base64').toString('binary'), 0); await driver.addCredential(nonResidentCredential); let credentialList = await driver.getCredentials(); assert.equal(1, credentialList.length); let credential_id = credentialList[0].id(); let test_id = new Uint8Array([1, 2, 3, 4]); assert(arraysEqual(credential_id, test_id)); }); it('Get credential', async function() { options.setProtocol(Protocol['CTAP2']); options.setHasResidentKey(true); options.setHasUserVerification(true); options.setIsUserVerified(true); await driver.addVirtualAuthenticator(options); let residentCredential = new Credential().createResidentCredential( new Uint8Array([1, 2, 3, 4]), 'localhost', new Uint8Array([1]), Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'), 0); await driver.addCredential(residentCredential); let credentialList = await driver.getCredentials(); assert.equal(1, credentialList.length); let credential_id = credentialList[0].id(); let test_id = new Uint8Array([1, 2, 3, 4]); assert(arraysEqual(credential_id, test_id)); assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64')); }); it('Remove all credentials', async function() { await driver.addVirtualAuthenticator(options); let nonResidentCredential = new Credential().createNonResidentCredential( new Uint8Array([1, 2, 3, 4]), 'localhost', Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'), 0); await driver.addCredential(nonResidentCredential); await driver.removeAllCredentials(); let credentialList = await driver.getCredentials(); assert.equal(0, credentialList.length); }); it('Set is user verified', async function() { options.setIsUserVerified(true); assert.equal(options.getIsUserVerified(), true); }); });
Add Credential
Registra a credencial com o autenticador.
@Disabled("A fix was implemented and will be available in Selenium 4.34.") public void testCreateAndAddNonResidentialKey() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .setHasResidentKey(false); VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options); byte[] credentialId = {1, 2, 3, 4}; Credential nonResidentCredential = Credential.createNonResidentCredential(
examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java
package dev.selenium.interactions; import dev.selenium.BaseChromeTest; import java.security.spec.PKCS8EncodedKeySpec; import java.util.Base64; import java.util.List; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.openqa.selenium.InvalidArgumentException; import org.openqa.selenium.virtualauthenticator.Credential; import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator; import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator; import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions; public class VirtualAuthenticatorTest extends BaseChromeTest { /** * A pkcs#8 encoded encrypted RSA private key as a base64url string. */ private final static String base64EncodedRsaPK = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB" + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi" + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P" + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui" + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/" + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib" + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko" + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC" + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK" + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63" + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl" + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V" + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B" + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw" + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI" + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB" + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g=="; private final static PKCS8EncodedKeySpec rsaPrivateKey = new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK)); // A pkcs#8 encoded unencrypted EC256 private key as a base64url string. String base64EncodedEC256PK = "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB"; PKCS8EncodedKeySpec ec256PrivateKey = new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK)); @Test public void testVirtualOptions() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setIsUserVerified(true) .setHasUserVerification(true) .setIsUserConsenting(true) .setTransport(VirtualAuthenticatorOptions.Transport.USB) .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .setHasResidentKey(false); Assertions.assertEquals(6, options.toMap().size()); } @Test public void testCreateAuthenticator() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .setHasResidentKey(false); VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options); List<Credential> credentialList = authenticator.getCredentials(); Assertions.assertEquals(0, credentialList.size()); } @Test public void testRemoveAuthenticator() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions(); VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options); ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator); Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials); } @Test public void testCreateAndAddResidentialKey() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2) .setHasResidentKey(true) .setHasUserVerification(true) .setIsUserVerified(true); VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options); byte[] credentialId = {1, 2, 3, 4}; byte[] userHandle = {1}; Credential residentCredential = Credential.createResidentCredential( credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0); authenticator.addCredential(residentCredential); List<Credential> credentialList = authenticator.getCredentials(); Assertions.assertEquals(1, credentialList.size()); Credential credential = credentialList.get(0); Assertions.assertArrayEquals(credentialId, credential.getId()); } @Test public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .setHasResidentKey(true); VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options); PKCS8EncodedKeySpec privateKey = new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK)); byte[] credentialId = {1, 2, 3, 4}; byte[] userHandle = {1}; Credential credential = Credential.createResidentCredential( credentialId, "localhost", privateKey, userHandle, /*signCount=*/0); Assertions.assertThrows(InvalidArgumentException.class, () -> authenticator.addCredential(credential)); } @Test @Disabled("A fix was implemented and will be available in Selenium 4.34.") public void testCreateAndAddNonResidentialKey() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .setHasResidentKey(false); VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options); byte[] credentialId = {1, 2, 3, 4}; Credential nonResidentCredential = Credential.createNonResidentCredential( credentialId, "localhost", ec256PrivateKey, /*signCount=*/0); authenticator.addCredential(nonResidentCredential); List<Credential> credentialList = authenticator.getCredentials(); Assertions.assertEquals(1, credentialList.size()); Credential credential = credentialList.get(0); Assertions.assertArrayEquals(credentialId, credential.getId()); } @Test public void testGetCredential() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2) .setHasResidentKey(true) .setHasUserVerification(true) .setIsUserVerified(true); VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options); byte[] credentialId = {1, 2, 3, 4}; byte[] userHandle = {1}; Credential residentCredential = Credential.createResidentCredential( credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0); authenticator.addCredential(residentCredential); List<Credential> credentialList = authenticator.getCredentials(); Assertions.assertEquals(1, credentialList.size()); Credential credential = credentialList.get(0); Assertions.assertArrayEquals(credentialId, credential.getId()); Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded()); } @Test public void testRemoveCredential() { VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions()); byte[] credentialId = {1, 2, 3, 4}; Credential credential = Credential.createNonResidentCredential( credentialId, "localhost", rsaPrivateKey, 0); authenticator.addCredential(credential); authenticator.removeCredential(credentialId); Assertions.assertEquals(0, authenticator.getCredentials().size()); } @Test public void testRemoveAllCredentials() { VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions()); byte[] credentialId = {1, 2, 3, 4}; Credential residentCredential = Credential.createNonResidentCredential( credentialId, "localhost", rsaPrivateKey, /*signCount=*/0); authenticator.addCredential(residentCredential); authenticator.removeAllCredentials(); Assertions.assertEquals(0, authenticator.getCredentials().size()); } @Test public void testSetUserVerified() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setIsUserVerified(true); Assertions.assertTrue((boolean) options.toMap().get("isUserVerified")); } }
VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .SetHasResidentKey(false); ((WebDriver)driver).AddVirtualAuthenticator(options); byte[] credentialId = { 1, 2, 3, 4 }; Credential nonResidentCredential = Credential.CreateNonResidentCredential( credentialId, "localhost", base64EncodedEC256PK, 0); ((WebDriver)driver).AddCredential(nonResidentCredential);
examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs
using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.IdentityModel.Tokens; using OpenQA.Selenium; using OpenQA.Selenium.VirtualAuth; using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions; using System.Collections.Generic; using System; namespace SeleniumDocs.VirtualAuthentication { [TestClass] public class VirtualAuthenticatorTest : BaseChromeTest { //A pkcs#8 encoded encrypted RSA private key as a base64 string. private static string base64EncodedRSAPK = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB" + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi" + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P" + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui" + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/" + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib" + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko" + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC" + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK" + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63" + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl" + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V" + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B" + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw" + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI" + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB" + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g=="; private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK); private string base64EncodedPK = Base64UrlEncoder.Encode(bytes); // A pkcs#8 encoded unencrypted EC256 private key as a base64url string. private string base64EncodedEC256PK = "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB"; [TestMethod] public void VirtualOptionsShouldAllowSettingOptions() { // Create virtual authenticator options VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetIsUserVerified(true) .SetHasUserVerification(true) .SetIsUserConsenting(true) .SetTransport(VirtualAuthenticatorOptions.Transport.USB) .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .SetHasResidentKey(false); Assert.AreEqual(6, options.ToDictionary().Count); } [TestMethod] public void ShouldBeAbleToCreateAuthenticator() { // Create virtual authenticator options VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .SetHasResidentKey(false); // Register a virtual authenticator ((WebDriver)driver).AddVirtualAuthenticator(options); List<Credential> credentialList = ((WebDriver)driver).GetCredentials(); Assert.AreEqual(0, credentialList.Count); } [TestMethod] public void ShouldBeAbleToRemoveAuthenticator() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .SetHasResidentKey(false); String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options); ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId); // Since the authenticator was removed, any operation using it will throw an error Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials()); } [TestMethod] public void ShouldBeAbleToCreateAndAddResidentialKey() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetProtocol(Protocol.CTAP2) .SetHasResidentKey(true) .SetHasUserVerification(true) .SetIsUserVerified(true); ((WebDriver)driver).AddVirtualAuthenticator(options); byte[] credentialId = { 1, 2, 3, 4 }; byte[] userHandle = { 1 }; Credential residentCredential = Credential.CreateResidentCredential( credentialId, "localhost", base64EncodedPK, userHandle, 0); ((WebDriver)driver).AddCredential(residentCredential); List<Credential> credentialList = ((WebDriver)driver).GetCredentials(); Assert.AreEqual(1, credentialList.Count); Credential credential = credentialList[0]; CollectionAssert.AreEqual(credentialId, credential.Id); } [TestMethod] public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .SetHasResidentKey(true); ((WebDriver)driver).AddVirtualAuthenticator(options); byte[] credentialId = { 1, 2, 3, 4 }; byte[] userHandle = { 1 }; Credential credential = Credential.CreateResidentCredential( credentialId, "localhost", base64EncodedEC256PK, userHandle, 0); Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential)); } [TestMethod] public void ShouldBeAbleToCreateAndAddNonResidentKey() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .SetHasResidentKey(false); ((WebDriver)driver).AddVirtualAuthenticator(options); byte[] credentialId = { 1, 2, 3, 4 }; Credential nonResidentCredential = Credential.CreateNonResidentCredential( credentialId, "localhost", base64EncodedEC256PK, 0); ((WebDriver)driver).AddCredential(nonResidentCredential); List<Credential> credentialList = ((WebDriver)driver).GetCredentials(); Assert.AreEqual(1, credentialList.Count); Credential credential = credentialList[0]; CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id); } [TestMethod] public void ShouldBeAbleToGetCredential() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetProtocol(Protocol.CTAP2) .SetHasResidentKey(true) .SetHasUserVerification(true) .SetIsUserVerified(true); ((WebDriver)driver).AddVirtualAuthenticator(options); byte[] credentialId = { 1, 2, 3, 4 }; byte[] userHandle = { 1 }; Credential residentCredential = Credential.CreateResidentCredential( credentialId, "localhost", base64EncodedPK, userHandle, 0); ((WebDriver)driver).AddCredential(residentCredential); List<Credential> credentialList = ((WebDriver)driver).GetCredentials(); Assert.AreEqual(1, credentialList.Count); Credential credential = credentialList[0]; CollectionAssert.AreEqual(credentialId, residentCredential.Id); Assert.AreEqual(base64EncodedPK, credential.PrivateKey); } [TestMethod] public void ShouldBeAbleToRemoveCredential() { ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions()); byte[] credentialId = { 1, 2, 3, 4 }; Credential nonResidentCredential = Credential.CreateNonResidentCredential( credentialId, "localhost", base64EncodedEC256PK, 0); ((WebDriver)driver).AddCredential(nonResidentCredential); ((WebDriver)driver).RemoveCredential(credentialId); Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count); } [TestMethod] public void ShouldBeAbleToRemoveAllCredentias() { ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions()); byte[] credentialId = { 1, 2, 3, 4 }; Credential nonResidentCredential = Credential.CreateNonResidentCredential( credentialId, "localhost", base64EncodedEC256PK, 0); ((WebDriver)driver).AddCredential(nonResidentCredential); ((WebDriver)driver).RemoveAllCredentials(); Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count); } [TestMethod] public void ShouldBeSetVerifiedOption() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetIsUserVerified(true); Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]); } } }
driver.add_credential(credential)
examples/python/tests/interactions/test_virtual_authenticator.py
import pytest from base64 import urlsafe_b64decode, urlsafe_b64encode from selenium.common.exceptions import InvalidArgumentException from selenium.webdriver.chrome.webdriver import WebDriver from selenium.webdriver.common.virtual_authenticator import ( Credential, VirtualAuthenticatorOptions, ) BASE64__ENCODED_PK = ''' MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0 +j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM 8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD /Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ 5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8 K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa 9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H BYGpI8g== ''' @pytest.fixture(scope="module", autouse=True) def driver(): yield WebDriver() def test_virtual_authenticator_options(): options = VirtualAuthenticatorOptions() options.is_user_verified = True options.has_user_verification = True options.is_user_consenting = True options.transport = VirtualAuthenticatorOptions.Transport.USB options.protocol = VirtualAuthenticatorOptions.Protocol.U2F options.has_resident_key = False assert len(options.to_dict()) == 6 def test_add_authenticator(driver): # Create virtual authenticator options options = VirtualAuthenticatorOptions() options.protocol = VirtualAuthenticatorOptions.Protocol.U2F options.has_resident_key = False # Register a virtual authenticator driver.add_virtual_authenticator(options) # Get list of credentials credential_list = driver.get_credentials() assert len(credential_list) == 0 def test_remove_authenticator(driver): # Create default virtual authenticator option options = VirtualAuthenticatorOptions() # Register a virtual authenticator driver.add_virtual_authenticator(options) # Remove virtual authenticator driver.remove_virtual_authenticator() assert driver.virtual_authenticator_id is None def test_create_and_add_resident_key(driver): # Create virtual authenticator options options = VirtualAuthenticatorOptions() options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2 options.has_resident_key = True options.has_user_verification = True options.is_user_verified = True # Register a virtual authenticator driver.add_virtual_authenticator(options) # parameters for Resident Credential credential_id = bytearray({1, 2, 3, 4}) rp_id = "localhost" user_handle = bytearray({1}) privatekey = urlsafe_b64decode(BASE64__ENCODED_PK) sign_count = 0 # create a resident credential using above parameters resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count) # add the credential created to virtual authenticator driver.add_credential(resident_credential) # get list of all the registered credentials credential_list = driver.get_credentials() assert len(credential_list) == 1 def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver): # Create virtual authenticator options options = VirtualAuthenticatorOptions() options.protocol = VirtualAuthenticatorOptions.Protocol.U2F options.has_resident_key = False # Register a virtual authenticator driver.add_virtual_authenticator(options) # parameters for Resident Credential credential_id = bytearray({1, 2, 3, 4}) rp_id = "localhost" user_handle = bytearray({1}) privatekey = urlsafe_b64decode(BASE64__ENCODED_PK) sign_count = 0 # create a resident credential using above parameters credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count) # Expect InvalidArgumentException with pytest.raises(InvalidArgumentException): driver.add_credential(credential) def test_create_and_add_non_resident_key(driver): # Create virtual authenticator options options = VirtualAuthenticatorOptions() options.protocol = VirtualAuthenticatorOptions.Protocol.U2F options.has_resident_key = False # Register a virtual authenticator driver.add_virtual_authenticator(options) # parameters for Non Resident Credential credential_id = bytearray({1, 2, 3, 4}) rp_id = "localhost" privatekey = urlsafe_b64decode(BASE64__ENCODED_PK) sign_count = 0 # create a non resident credential using above parameters credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count) # add the credential created to virtual authenticator driver.add_credential(credential) # get list of all the registered credentials credential_list = driver.get_credentials() assert len(credential_list) == 1 def test_get_credential(driver): # Create virtual authenticator options options = VirtualAuthenticatorOptions() options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2 options.has_resident_key = True options.has_user_verfied = True options.is_user_verified = True # Register a virtual authenticator driver.add_virtual_authenticator(options) # parameters for Resident Credential credential_id = bytearray({1, 2, 3, 4}) rp_id = "localhost" user_handle = bytearray({1}) privatekey = urlsafe_b64decode(BASE64__ENCODED_PK) sign_count = 0 # create a resident credential using above parameters credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count) # add the credential created to virtual authenticator driver.add_credential(credential) # get list of all the registered credentials credential_list = driver.get_credentials() assert len(credential_list) == 1 assert credential_list[0].id == urlsafe_b64encode(credential_id).decode() def test_remove_credential(driver): # Create default virtual authenticator options options = VirtualAuthenticatorOptions() # Register a virtual authenticator driver.add_virtual_authenticator(options) # parameters for Non Resident Credential credential_id = bytearray({1, 2, 3, 4}) rp_id = "localhost" privatekey = urlsafe_b64decode(BASE64__ENCODED_PK) sign_count = 0 # create a non resident credential using above parameters credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count) # add the credential created to virtual authenticator driver.add_credential(credential) # remove the credential created from virtual authenticator driver.remove_credential(credential.id) # credential can also be removed using Byte Array # driver.remove_credential(credential_id) assert len(driver.get_credentials()) == 0 def test_remove_all_credentials(driver): # Create default virtual authenticator options options = VirtualAuthenticatorOptions() options.has_resident_key = True # Register a virtual authenticator driver.add_virtual_authenticator(options) # parameters for Resident Credential credential_id = bytearray({1, 2, 3, 4}) rp_id = "localhost" user_handle = bytearray({1}) privatekey = urlsafe_b64decode(BASE64__ENCODED_PK) sign_count = 0 # create a resident credential using above parameters resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count) # add the credential created to virtual authenticator driver.add_credential(resident_credential) # remove all credentials in virtual authenticator driver.remove_all_credentials() assert len(driver.get_credentials()) == 0 def test_set_user_verified(): # Create virtual authenticator options options = VirtualAuthenticatorOptions() options.is_user_verified = True assert options.to_dict().get("isUserVerified") is True
options.setProtocol(Protocol['U2F']); options.setHasResidentKey(false); await driver.addVirtualAuthenticator(options); let nonResidentCredential = new Credential().createNonResidentCredential( new Uint8Array([1, 2, 3, 4]), 'localhost', Buffer.from(base64EncodedPK, 'base64').toString('binary'), 0); await driver.addCredential(nonResidentCredential);
examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js
const { Builder} = require("selenium-webdriver"); const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator"); const assert = require('assert') const { InvalidArgumentError } = require("selenium-webdriver/lib/error"); describe('Virtual authenticator', function() { const BASE64_ENCODED_PK = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" + "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" + "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" + "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" + "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" + "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" + "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" + "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" + "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" + "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" + "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" + "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" + "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" + "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" + "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" + "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" + "BYGpI8g=="; const base64EncodedPK = "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB"; let options; let driver; before(async function() { options = new VirtualAuthenticatorOptions(); driver = await new Builder().forBrowser('chrome').build(); }); after(async() => await driver.quit()); function arraysEqual(array1, array2) { return (array1.length === array2.length && array1.every((item) => array2.includes(item)) && array2.every((item) => array1.includes(item))); } it('Register a virtual authenticator', async function() { options.setProtocol(Protocol['U2F']); options.setHasResidentKey(false); // Register a virtual authenticator await driver.addVirtualAuthenticator(options); let credentialList = await driver.getCredentials(); assert.equal(0, credentialList.length); }); it('Remove authenticator', async function() { await driver.addVirtualAuthenticator(options); await driver.removeVirtualAuthenticator(); // Since the authenticator was removed, any operation using it will throw an error try { await driver.getCredentials() } catch (e) { if (e instanceof InvalidArgumentError) { assert(true) } else { assert(false) } } }); it('Createa and add residential key', async function() { options.setProtocol(Protocol['CTAP2']); options.setHasResidentKey(true); options.setHasUserVerification(true); options.setIsUserVerified(true); await driver.addVirtualAuthenticator(options); let residentCredential = new Credential().createResidentCredential( new Uint8Array([1, 2, 3, 4]), 'localhost', new Uint8Array([1]), Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'), 0); await driver.addCredential(residentCredential); let credentialList = await driver.getCredentials(); assert.equal(1, credentialList.length); let credential_id = credentialList[0].id(); let test_id = new Uint8Array([1, 2, 3, 4]); assert(arraysEqual(credential_id, test_id)); }); it('Add resident credential not supported when authenticator uses U2F protocol', async function() { options.setProtocol(Protocol['U2F']); options.setHasResidentKey(true); await driver.addVirtualAuthenticator(options); let credential = new Credential().createResidentCredential( new Uint8Array([1, 2, 3, 4]), 'localhost', new Uint8Array([1]), Buffer.from(base64EncodedPK, 'base64').toString('binary'), 0); try { await driver.addCredential(credential) } catch (e) { if (e instanceof InvalidArgumentError) { assert(true) } else { assert(false) } } }); it('Create and add non residential key', async function() { options.setProtocol(Protocol['U2F']); options.setHasResidentKey(false); await driver.addVirtualAuthenticator(options); let nonResidentCredential = new Credential().createNonResidentCredential( new Uint8Array([1, 2, 3, 4]), 'localhost', Buffer.from(base64EncodedPK, 'base64').toString('binary'), 0); await driver.addCredential(nonResidentCredential); let credentialList = await driver.getCredentials(); assert.equal(1, credentialList.length); let credential_id = credentialList[0].id(); let test_id = new Uint8Array([1, 2, 3, 4]); assert(arraysEqual(credential_id, test_id)); }); it('Get credential', async function() { options.setProtocol(Protocol['CTAP2']); options.setHasResidentKey(true); options.setHasUserVerification(true); options.setIsUserVerified(true); await driver.addVirtualAuthenticator(options); let residentCredential = new Credential().createResidentCredential( new Uint8Array([1, 2, 3, 4]), 'localhost', new Uint8Array([1]), Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'), 0); await driver.addCredential(residentCredential); let credentialList = await driver.getCredentials(); assert.equal(1, credentialList.length); let credential_id = credentialList[0].id(); let test_id = new Uint8Array([1, 2, 3, 4]); assert(arraysEqual(credential_id, test_id)); assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64')); }); it('Remove all credentials', async function() { await driver.addVirtualAuthenticator(options); let nonResidentCredential = new Credential().createNonResidentCredential( new Uint8Array([1, 2, 3, 4]), 'localhost', Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'), 0); await driver.addCredential(nonResidentCredential); await driver.removeAllCredentials(); let credentialList = await driver.getCredentials(); assert.equal(0, credentialList.length); }); it('Set is user verified', async function() { options.setIsUserVerified(true); assert.equal(options.getIsUserVerified(), true); }); });
Get Credential
Retorna a lista de credenciais que o autenticador possui.
@Test public void testGetCredential() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2) .setHasResidentKey(true) .setHasUserVerification(true) .setIsUserVerified(true); VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options); byte[] credentialId = {1, 2, 3, 4}; byte[] userHandle = {1}; Credential residentCredential = Credential.createResidentCredential( credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0); authenticator.addCredential(residentCredential);
examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java
package dev.selenium.interactions; import dev.selenium.BaseChromeTest; import java.security.spec.PKCS8EncodedKeySpec; import java.util.Base64; import java.util.List; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.openqa.selenium.InvalidArgumentException; import org.openqa.selenium.virtualauthenticator.Credential; import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator; import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator; import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions; public class VirtualAuthenticatorTest extends BaseChromeTest { /** * A pkcs#8 encoded encrypted RSA private key as a base64url string. */ private final static String base64EncodedRsaPK = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB" + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi" + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P" + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui" + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/" + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib" + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko" + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC" + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK" + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63" + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl" + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V" + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B" + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw" + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI" + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB" + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g=="; private final static PKCS8EncodedKeySpec rsaPrivateKey = new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK)); // A pkcs#8 encoded unencrypted EC256 private key as a base64url string. String base64EncodedEC256PK = "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB"; PKCS8EncodedKeySpec ec256PrivateKey = new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK)); @Test public void testVirtualOptions() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setIsUserVerified(true) .setHasUserVerification(true) .setIsUserConsenting(true) .setTransport(VirtualAuthenticatorOptions.Transport.USB) .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .setHasResidentKey(false); Assertions.assertEquals(6, options.toMap().size()); } @Test public void testCreateAuthenticator() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .setHasResidentKey(false); VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options); List<Credential> credentialList = authenticator.getCredentials(); Assertions.assertEquals(0, credentialList.size()); } @Test public void testRemoveAuthenticator() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions(); VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options); ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator); Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials); } @Test public void testCreateAndAddResidentialKey() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2) .setHasResidentKey(true) .setHasUserVerification(true) .setIsUserVerified(true); VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options); byte[] credentialId = {1, 2, 3, 4}; byte[] userHandle = {1}; Credential residentCredential = Credential.createResidentCredential( credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0); authenticator.addCredential(residentCredential); List<Credential> credentialList = authenticator.getCredentials(); Assertions.assertEquals(1, credentialList.size()); Credential credential = credentialList.get(0); Assertions.assertArrayEquals(credentialId, credential.getId()); } @Test public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .setHasResidentKey(true); VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options); PKCS8EncodedKeySpec privateKey = new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK)); byte[] credentialId = {1, 2, 3, 4}; byte[] userHandle = {1}; Credential credential = Credential.createResidentCredential( credentialId, "localhost", privateKey, userHandle, /*signCount=*/0); Assertions.assertThrows(InvalidArgumentException.class, () -> authenticator.addCredential(credential)); } @Test @Disabled("A fix was implemented and will be available in Selenium 4.34.") public void testCreateAndAddNonResidentialKey() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .setHasResidentKey(false); VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options); byte[] credentialId = {1, 2, 3, 4}; Credential nonResidentCredential = Credential.createNonResidentCredential( credentialId, "localhost", ec256PrivateKey, /*signCount=*/0); authenticator.addCredential(nonResidentCredential); List<Credential> credentialList = authenticator.getCredentials(); Assertions.assertEquals(1, credentialList.size()); Credential credential = credentialList.get(0); Assertions.assertArrayEquals(credentialId, credential.getId()); } @Test public void testGetCredential() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2) .setHasResidentKey(true) .setHasUserVerification(true) .setIsUserVerified(true); VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options); byte[] credentialId = {1, 2, 3, 4}; byte[] userHandle = {1}; Credential residentCredential = Credential.createResidentCredential( credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0); authenticator.addCredential(residentCredential); List<Credential> credentialList = authenticator.getCredentials(); Assertions.assertEquals(1, credentialList.size()); Credential credential = credentialList.get(0); Assertions.assertArrayEquals(credentialId, credential.getId()); Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded()); } @Test public void testRemoveCredential() { VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions()); byte[] credentialId = {1, 2, 3, 4}; Credential credential = Credential.createNonResidentCredential( credentialId, "localhost", rsaPrivateKey, 0); authenticator.addCredential(credential); authenticator.removeCredential(credentialId); Assertions.assertEquals(0, authenticator.getCredentials().size()); } @Test public void testRemoveAllCredentials() { VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions()); byte[] credentialId = {1, 2, 3, 4}; Credential residentCredential = Credential.createNonResidentCredential( credentialId, "localhost", rsaPrivateKey, /*signCount=*/0); authenticator.addCredential(residentCredential); authenticator.removeAllCredentials(); Assertions.assertEquals(0, authenticator.getCredentials().size()); } @Test public void testSetUserVerified() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setIsUserVerified(true); Assertions.assertTrue((boolean) options.toMap().get("isUserVerified")); } }
VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetProtocol(Protocol.CTAP2) .SetHasResidentKey(true) .SetHasUserVerification(true) .SetIsUserVerified(true); ((WebDriver)driver).AddVirtualAuthenticator(options); byte[] credentialId = { 1, 2, 3, 4 }; byte[] userHandle = { 1 }; Credential residentCredential = Credential.CreateResidentCredential( credentialId, "localhost", base64EncodedPK, userHandle, 0); ((WebDriver)driver).AddCredential(residentCredential); List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs
using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.IdentityModel.Tokens; using OpenQA.Selenium; using OpenQA.Selenium.VirtualAuth; using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions; using System.Collections.Generic; using System; namespace SeleniumDocs.VirtualAuthentication { [TestClass] public class VirtualAuthenticatorTest : BaseChromeTest { //A pkcs#8 encoded encrypted RSA private key as a base64 string. private static string base64EncodedRSAPK = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB" + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi" + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P" + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui" + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/" + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib" + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko" + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC" + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK" + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63" + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl" + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V" + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B" + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw" + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI" + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB" + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g=="; private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK); private string base64EncodedPK = Base64UrlEncoder.Encode(bytes); // A pkcs#8 encoded unencrypted EC256 private key as a base64url string. private string base64EncodedEC256PK = "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB"; [TestMethod] public void VirtualOptionsShouldAllowSettingOptions() { // Create virtual authenticator options VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetIsUserVerified(true) .SetHasUserVerification(true) .SetIsUserConsenting(true) .SetTransport(VirtualAuthenticatorOptions.Transport.USB) .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .SetHasResidentKey(false); Assert.AreEqual(6, options.ToDictionary().Count); } [TestMethod] public void ShouldBeAbleToCreateAuthenticator() { // Create virtual authenticator options VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .SetHasResidentKey(false); // Register a virtual authenticator ((WebDriver)driver).AddVirtualAuthenticator(options); List<Credential> credentialList = ((WebDriver)driver).GetCredentials(); Assert.AreEqual(0, credentialList.Count); } [TestMethod] public void ShouldBeAbleToRemoveAuthenticator() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .SetHasResidentKey(false); String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options); ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId); // Since the authenticator was removed, any operation using it will throw an error Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials()); } [TestMethod] public void ShouldBeAbleToCreateAndAddResidentialKey() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetProtocol(Protocol.CTAP2) .SetHasResidentKey(true) .SetHasUserVerification(true) .SetIsUserVerified(true); ((WebDriver)driver).AddVirtualAuthenticator(options); byte[] credentialId = { 1, 2, 3, 4 }; byte[] userHandle = { 1 }; Credential residentCredential = Credential.CreateResidentCredential( credentialId, "localhost", base64EncodedPK, userHandle, 0); ((WebDriver)driver).AddCredential(residentCredential); List<Credential> credentialList = ((WebDriver)driver).GetCredentials(); Assert.AreEqual(1, credentialList.Count); Credential credential = credentialList[0]; CollectionAssert.AreEqual(credentialId, credential.Id); } [TestMethod] public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .SetHasResidentKey(true); ((WebDriver)driver).AddVirtualAuthenticator(options); byte[] credentialId = { 1, 2, 3, 4 }; byte[] userHandle = { 1 }; Credential credential = Credential.CreateResidentCredential( credentialId, "localhost", base64EncodedEC256PK, userHandle, 0); Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential)); } [TestMethod] public void ShouldBeAbleToCreateAndAddNonResidentKey() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .SetHasResidentKey(false); ((WebDriver)driver).AddVirtualAuthenticator(options); byte[] credentialId = { 1, 2, 3, 4 }; Credential nonResidentCredential = Credential.CreateNonResidentCredential( credentialId, "localhost", base64EncodedEC256PK, 0); ((WebDriver)driver).AddCredential(nonResidentCredential); List<Credential> credentialList = ((WebDriver)driver).GetCredentials(); Assert.AreEqual(1, credentialList.Count); Credential credential = credentialList[0]; CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id); } [TestMethod] public void ShouldBeAbleToGetCredential() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetProtocol(Protocol.CTAP2) .SetHasResidentKey(true) .SetHasUserVerification(true) .SetIsUserVerified(true); ((WebDriver)driver).AddVirtualAuthenticator(options); byte[] credentialId = { 1, 2, 3, 4 }; byte[] userHandle = { 1 }; Credential residentCredential = Credential.CreateResidentCredential( credentialId, "localhost", base64EncodedPK, userHandle, 0); ((WebDriver)driver).AddCredential(residentCredential); List<Credential> credentialList = ((WebDriver)driver).GetCredentials(); Assert.AreEqual(1, credentialList.Count); Credential credential = credentialList[0]; CollectionAssert.AreEqual(credentialId, residentCredential.Id); Assert.AreEqual(base64EncodedPK, credential.PrivateKey); } [TestMethod] public void ShouldBeAbleToRemoveCredential() { ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions()); byte[] credentialId = { 1, 2, 3, 4 }; Credential nonResidentCredential = Credential.CreateNonResidentCredential( credentialId, "localhost", base64EncodedEC256PK, 0); ((WebDriver)driver).AddCredential(nonResidentCredential); ((WebDriver)driver).RemoveCredential(credentialId); Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count); } [TestMethod] public void ShouldBeAbleToRemoveAllCredentias() { ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions()); byte[] credentialId = { 1, 2, 3, 4 }; Credential nonResidentCredential = Credential.CreateNonResidentCredential( credentialId, "localhost", base64EncodedEC256PK, 0); ((WebDriver)driver).AddCredential(nonResidentCredential); ((WebDriver)driver).RemoveAllCredentials(); Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count); } [TestMethod] public void ShouldBeSetVerifiedOption() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetIsUserVerified(true); Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]); } } }
credential_list = driver.get_credentials()
examples/python/tests/interactions/test_virtual_authenticator.py
import pytest from base64 import urlsafe_b64decode, urlsafe_b64encode from selenium.common.exceptions import InvalidArgumentException from selenium.webdriver.chrome.webdriver import WebDriver from selenium.webdriver.common.virtual_authenticator import ( Credential, VirtualAuthenticatorOptions, ) BASE64__ENCODED_PK = ''' MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0 +j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM 8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD /Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ 5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8 K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa 9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H BYGpI8g== ''' @pytest.fixture(scope="module", autouse=True) def driver(): yield WebDriver() def test_virtual_authenticator_options(): options = VirtualAuthenticatorOptions() options.is_user_verified = True options.has_user_verification = True options.is_user_consenting = True options.transport = VirtualAuthenticatorOptions.Transport.USB options.protocol = VirtualAuthenticatorOptions.Protocol.U2F options.has_resident_key = False assert len(options.to_dict()) == 6 def test_add_authenticator(driver): # Create virtual authenticator options options = VirtualAuthenticatorOptions() options.protocol = VirtualAuthenticatorOptions.Protocol.U2F options.has_resident_key = False # Register a virtual authenticator driver.add_virtual_authenticator(options) # Get list of credentials credential_list = driver.get_credentials() assert len(credential_list) == 0 def test_remove_authenticator(driver): # Create default virtual authenticator option options = VirtualAuthenticatorOptions() # Register a virtual authenticator driver.add_virtual_authenticator(options) # Remove virtual authenticator driver.remove_virtual_authenticator() assert driver.virtual_authenticator_id is None def test_create_and_add_resident_key(driver): # Create virtual authenticator options options = VirtualAuthenticatorOptions() options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2 options.has_resident_key = True options.has_user_verification = True options.is_user_verified = True # Register a virtual authenticator driver.add_virtual_authenticator(options) # parameters for Resident Credential credential_id = bytearray({1, 2, 3, 4}) rp_id = "localhost" user_handle = bytearray({1}) privatekey = urlsafe_b64decode(BASE64__ENCODED_PK) sign_count = 0 # create a resident credential using above parameters resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count) # add the credential created to virtual authenticator driver.add_credential(resident_credential) # get list of all the registered credentials credential_list = driver.get_credentials() assert len(credential_list) == 1 def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver): # Create virtual authenticator options options = VirtualAuthenticatorOptions() options.protocol = VirtualAuthenticatorOptions.Protocol.U2F options.has_resident_key = False # Register a virtual authenticator driver.add_virtual_authenticator(options) # parameters for Resident Credential credential_id = bytearray({1, 2, 3, 4}) rp_id = "localhost" user_handle = bytearray({1}) privatekey = urlsafe_b64decode(BASE64__ENCODED_PK) sign_count = 0 # create a resident credential using above parameters credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count) # Expect InvalidArgumentException with pytest.raises(InvalidArgumentException): driver.add_credential(credential) def test_create_and_add_non_resident_key(driver): # Create virtual authenticator options options = VirtualAuthenticatorOptions() options.protocol = VirtualAuthenticatorOptions.Protocol.U2F options.has_resident_key = False # Register a virtual authenticator driver.add_virtual_authenticator(options) # parameters for Non Resident Credential credential_id = bytearray({1, 2, 3, 4}) rp_id = "localhost" privatekey = urlsafe_b64decode(BASE64__ENCODED_PK) sign_count = 0 # create a non resident credential using above parameters credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count) # add the credential created to virtual authenticator driver.add_credential(credential) # get list of all the registered credentials credential_list = driver.get_credentials() assert len(credential_list) == 1 def test_get_credential(driver): # Create virtual authenticator options options = VirtualAuthenticatorOptions() options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2 options.has_resident_key = True options.has_user_verfied = True options.is_user_verified = True # Register a virtual authenticator driver.add_virtual_authenticator(options) # parameters for Resident Credential credential_id = bytearray({1, 2, 3, 4}) rp_id = "localhost" user_handle = bytearray({1}) privatekey = urlsafe_b64decode(BASE64__ENCODED_PK) sign_count = 0 # create a resident credential using above parameters credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count) # add the credential created to virtual authenticator driver.add_credential(credential) # get list of all the registered credentials credential_list = driver.get_credentials() assert len(credential_list) == 1 assert credential_list[0].id == urlsafe_b64encode(credential_id).decode() def test_remove_credential(driver): # Create default virtual authenticator options options = VirtualAuthenticatorOptions() # Register a virtual authenticator driver.add_virtual_authenticator(options) # parameters for Non Resident Credential credential_id = bytearray({1, 2, 3, 4}) rp_id = "localhost" privatekey = urlsafe_b64decode(BASE64__ENCODED_PK) sign_count = 0 # create a non resident credential using above parameters credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count) # add the credential created to virtual authenticator driver.add_credential(credential) # remove the credential created from virtual authenticator driver.remove_credential(credential.id) # credential can also be removed using Byte Array # driver.remove_credential(credential_id) assert len(driver.get_credentials()) == 0 def test_remove_all_credentials(driver): # Create default virtual authenticator options options = VirtualAuthenticatorOptions() options.has_resident_key = True # Register a virtual authenticator driver.add_virtual_authenticator(options) # parameters for Resident Credential credential_id = bytearray({1, 2, 3, 4}) rp_id = "localhost" user_handle = bytearray({1}) privatekey = urlsafe_b64decode(BASE64__ENCODED_PK) sign_count = 0 # create a resident credential using above parameters resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count) # add the credential created to virtual authenticator driver.add_credential(resident_credential) # remove all credentials in virtual authenticator driver.remove_all_credentials() assert len(driver.get_credentials()) == 0 def test_set_user_verified(): # Create virtual authenticator options options = VirtualAuthenticatorOptions() options.is_user_verified = True assert options.to_dict().get("isUserVerified") is True
options.setProtocol(Protocol['CTAP2']); options.setHasResidentKey(true); options.setHasUserVerification(true); options.setIsUserVerified(true); await driver.addVirtualAuthenticator(options); let residentCredential = new Credential().createResidentCredential( new Uint8Array([1, 2, 3, 4]), 'localhost', new Uint8Array([1]), Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'), 0); await driver.addCredential(residentCredential); let credentialList = await driver.getCredentials();
examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js
const { Builder} = require("selenium-webdriver"); const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator"); const assert = require('assert') const { InvalidArgumentError } = require("selenium-webdriver/lib/error"); describe('Virtual authenticator', function() { const BASE64_ENCODED_PK = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" + "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" + "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" + "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" + "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" + "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" + "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" + "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" + "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" + "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" + "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" + "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" + "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" + "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" + "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" + "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" + "BYGpI8g=="; const base64EncodedPK = "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB"; let options; let driver; before(async function() { options = new VirtualAuthenticatorOptions(); driver = await new Builder().forBrowser('chrome').build(); }); after(async() => await driver.quit()); function arraysEqual(array1, array2) { return (array1.length === array2.length && array1.every((item) => array2.includes(item)) && array2.every((item) => array1.includes(item))); } it('Register a virtual authenticator', async function() { options.setProtocol(Protocol['U2F']); options.setHasResidentKey(false); // Register a virtual authenticator await driver.addVirtualAuthenticator(options); let credentialList = await driver.getCredentials(); assert.equal(0, credentialList.length); }); it('Remove authenticator', async function() { await driver.addVirtualAuthenticator(options); await driver.removeVirtualAuthenticator(); // Since the authenticator was removed, any operation using it will throw an error try { await driver.getCredentials() } catch (e) { if (e instanceof InvalidArgumentError) { assert(true) } else { assert(false) } } }); it('Createa and add residential key', async function() { options.setProtocol(Protocol['CTAP2']); options.setHasResidentKey(true); options.setHasUserVerification(true); options.setIsUserVerified(true); await driver.addVirtualAuthenticator(options); let residentCredential = new Credential().createResidentCredential( new Uint8Array([1, 2, 3, 4]), 'localhost', new Uint8Array([1]), Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'), 0); await driver.addCredential(residentCredential); let credentialList = await driver.getCredentials(); assert.equal(1, credentialList.length); let credential_id = credentialList[0].id(); let test_id = new Uint8Array([1, 2, 3, 4]); assert(arraysEqual(credential_id, test_id)); }); it('Add resident credential not supported when authenticator uses U2F protocol', async function() { options.setProtocol(Protocol['U2F']); options.setHasResidentKey(true); await driver.addVirtualAuthenticator(options); let credential = new Credential().createResidentCredential( new Uint8Array([1, 2, 3, 4]), 'localhost', new Uint8Array([1]), Buffer.from(base64EncodedPK, 'base64').toString('binary'), 0); try { await driver.addCredential(credential) } catch (e) { if (e instanceof InvalidArgumentError) { assert(true) } else { assert(false) } } }); it('Create and add non residential key', async function() { options.setProtocol(Protocol['U2F']); options.setHasResidentKey(false); await driver.addVirtualAuthenticator(options); let nonResidentCredential = new Credential().createNonResidentCredential( new Uint8Array([1, 2, 3, 4]), 'localhost', Buffer.from(base64EncodedPK, 'base64').toString('binary'), 0); await driver.addCredential(nonResidentCredential); let credentialList = await driver.getCredentials(); assert.equal(1, credentialList.length); let credential_id = credentialList[0].id(); let test_id = new Uint8Array([1, 2, 3, 4]); assert(arraysEqual(credential_id, test_id)); }); it('Get credential', async function() { options.setProtocol(Protocol['CTAP2']); options.setHasResidentKey(true); options.setHasUserVerification(true); options.setIsUserVerified(true); await driver.addVirtualAuthenticator(options); let residentCredential = new Credential().createResidentCredential( new Uint8Array([1, 2, 3, 4]), 'localhost', new Uint8Array([1]), Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'), 0); await driver.addCredential(residentCredential); let credentialList = await driver.getCredentials(); assert.equal(1, credentialList.length); let credential_id = credentialList[0].id(); let test_id = new Uint8Array([1, 2, 3, 4]); assert(arraysEqual(credential_id, test_id)); assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64')); }); it('Remove all credentials', async function() { await driver.addVirtualAuthenticator(options); let nonResidentCredential = new Credential().createNonResidentCredential( new Uint8Array([1, 2, 3, 4]), 'localhost', Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'), 0); await driver.addCredential(nonResidentCredential); await driver.removeAllCredentials(); let credentialList = await driver.getCredentials(); assert.equal(0, credentialList.length); }); it('Set is user verified', async function() { options.setIsUserVerified(true); assert.equal(options.getIsUserVerified(), true); }); });
Remove Credential
Remove a credencial do autenticador baseado na id da credencial passado.
((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions()); byte[] credentialId = { 1, 2, 3, 4 }; Credential nonResidentCredential = Credential.CreateNonResidentCredential( credentialId, "localhost", base64EncodedEC256PK, 0); ((WebDriver)driver).AddCredential(nonResidentCredential); ((WebDriver)driver).RemoveCredential(credentialId);
examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs
using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.IdentityModel.Tokens; using OpenQA.Selenium; using OpenQA.Selenium.VirtualAuth; using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions; using System.Collections.Generic; using System; namespace SeleniumDocs.VirtualAuthentication { [TestClass] public class VirtualAuthenticatorTest : BaseChromeTest { //A pkcs#8 encoded encrypted RSA private key as a base64 string. private static string base64EncodedRSAPK = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB" + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi" + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P" + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui" + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/" + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib" + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko" + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC" + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK" + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63" + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl" + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V" + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B" + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw" + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI" + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB" + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g=="; private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK); private string base64EncodedPK = Base64UrlEncoder.Encode(bytes); // A pkcs#8 encoded unencrypted EC256 private key as a base64url string. private string base64EncodedEC256PK = "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB"; [TestMethod] public void VirtualOptionsShouldAllowSettingOptions() { // Create virtual authenticator options VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetIsUserVerified(true) .SetHasUserVerification(true) .SetIsUserConsenting(true) .SetTransport(VirtualAuthenticatorOptions.Transport.USB) .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .SetHasResidentKey(false); Assert.AreEqual(6, options.ToDictionary().Count); } [TestMethod] public void ShouldBeAbleToCreateAuthenticator() { // Create virtual authenticator options VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .SetHasResidentKey(false); // Register a virtual authenticator ((WebDriver)driver).AddVirtualAuthenticator(options); List<Credential> credentialList = ((WebDriver)driver).GetCredentials(); Assert.AreEqual(0, credentialList.Count); } [TestMethod] public void ShouldBeAbleToRemoveAuthenticator() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .SetHasResidentKey(false); String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options); ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId); // Since the authenticator was removed, any operation using it will throw an error Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials()); } [TestMethod] public void ShouldBeAbleToCreateAndAddResidentialKey() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetProtocol(Protocol.CTAP2) .SetHasResidentKey(true) .SetHasUserVerification(true) .SetIsUserVerified(true); ((WebDriver)driver).AddVirtualAuthenticator(options); byte[] credentialId = { 1, 2, 3, 4 }; byte[] userHandle = { 1 }; Credential residentCredential = Credential.CreateResidentCredential( credentialId, "localhost", base64EncodedPK, userHandle, 0); ((WebDriver)driver).AddCredential(residentCredential); List<Credential> credentialList = ((WebDriver)driver).GetCredentials(); Assert.AreEqual(1, credentialList.Count); Credential credential = credentialList[0]; CollectionAssert.AreEqual(credentialId, credential.Id); } [TestMethod] public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .SetHasResidentKey(true); ((WebDriver)driver).AddVirtualAuthenticator(options); byte[] credentialId = { 1, 2, 3, 4 }; byte[] userHandle = { 1 }; Credential credential = Credential.CreateResidentCredential( credentialId, "localhost", base64EncodedEC256PK, userHandle, 0); Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential)); } [TestMethod] public void ShouldBeAbleToCreateAndAddNonResidentKey() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .SetHasResidentKey(false); ((WebDriver)driver).AddVirtualAuthenticator(options); byte[] credentialId = { 1, 2, 3, 4 }; Credential nonResidentCredential = Credential.CreateNonResidentCredential( credentialId, "localhost", base64EncodedEC256PK, 0); ((WebDriver)driver).AddCredential(nonResidentCredential); List<Credential> credentialList = ((WebDriver)driver).GetCredentials(); Assert.AreEqual(1, credentialList.Count); Credential credential = credentialList[0]; CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id); } [TestMethod] public void ShouldBeAbleToGetCredential() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetProtocol(Protocol.CTAP2) .SetHasResidentKey(true) .SetHasUserVerification(true) .SetIsUserVerified(true); ((WebDriver)driver).AddVirtualAuthenticator(options); byte[] credentialId = { 1, 2, 3, 4 }; byte[] userHandle = { 1 }; Credential residentCredential = Credential.CreateResidentCredential( credentialId, "localhost", base64EncodedPK, userHandle, 0); ((WebDriver)driver).AddCredential(residentCredential); List<Credential> credentialList = ((WebDriver)driver).GetCredentials(); Assert.AreEqual(1, credentialList.Count); Credential credential = credentialList[0]; CollectionAssert.AreEqual(credentialId, residentCredential.Id); Assert.AreEqual(base64EncodedPK, credential.PrivateKey); } [TestMethod] public void ShouldBeAbleToRemoveCredential() { ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions()); byte[] credentialId = { 1, 2, 3, 4 }; Credential nonResidentCredential = Credential.CreateNonResidentCredential( credentialId, "localhost", base64EncodedEC256PK, 0); ((WebDriver)driver).AddCredential(nonResidentCredential); ((WebDriver)driver).RemoveCredential(credentialId); Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count); } [TestMethod] public void ShouldBeAbleToRemoveAllCredentias() { ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions()); byte[] credentialId = { 1, 2, 3, 4 }; Credential nonResidentCredential = Credential.CreateNonResidentCredential( credentialId, "localhost", base64EncodedEC256PK, 0); ((WebDriver)driver).AddCredential(nonResidentCredential); ((WebDriver)driver).RemoveAllCredentials(); Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count); } [TestMethod] public void ShouldBeSetVerifiedOption() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetIsUserVerified(true); Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]); } } }
@Test public void testRemoveCredential() { VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions()); byte[] credentialId = {1, 2, 3, 4}; Credential credential = Credential.createNonResidentCredential( credentialId, "localhost", rsaPrivateKey, 0); authenticator.addCredential(credential);
examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java
package dev.selenium.interactions; import dev.selenium.BaseChromeTest; import java.security.spec.PKCS8EncodedKeySpec; import java.util.Base64; import java.util.List; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.openqa.selenium.InvalidArgumentException; import org.openqa.selenium.virtualauthenticator.Credential; import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator; import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator; import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions; public class VirtualAuthenticatorTest extends BaseChromeTest { /** * A pkcs#8 encoded encrypted RSA private key as a base64url string. */ private final static String base64EncodedRsaPK = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB" + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi" + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P" + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui" + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/" + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib" + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko" + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC" + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK" + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63" + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl" + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V" + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B" + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw" + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI" + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB" + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g=="; private final static PKCS8EncodedKeySpec rsaPrivateKey = new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK)); // A pkcs#8 encoded unencrypted EC256 private key as a base64url string. String base64EncodedEC256PK = "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB"; PKCS8EncodedKeySpec ec256PrivateKey = new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK)); @Test public void testVirtualOptions() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setIsUserVerified(true) .setHasUserVerification(true) .setIsUserConsenting(true) .setTransport(VirtualAuthenticatorOptions.Transport.USB) .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .setHasResidentKey(false); Assertions.assertEquals(6, options.toMap().size()); } @Test public void testCreateAuthenticator() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .setHasResidentKey(false); VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options); List<Credential> credentialList = authenticator.getCredentials(); Assertions.assertEquals(0, credentialList.size()); } @Test public void testRemoveAuthenticator() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions(); VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options); ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator); Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials); } @Test public void testCreateAndAddResidentialKey() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2) .setHasResidentKey(true) .setHasUserVerification(true) .setIsUserVerified(true); VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options); byte[] credentialId = {1, 2, 3, 4}; byte[] userHandle = {1}; Credential residentCredential = Credential.createResidentCredential( credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0); authenticator.addCredential(residentCredential); List<Credential> credentialList = authenticator.getCredentials(); Assertions.assertEquals(1, credentialList.size()); Credential credential = credentialList.get(0); Assertions.assertArrayEquals(credentialId, credential.getId()); } @Test public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .setHasResidentKey(true); VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options); PKCS8EncodedKeySpec privateKey = new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK)); byte[] credentialId = {1, 2, 3, 4}; byte[] userHandle = {1}; Credential credential = Credential.createResidentCredential( credentialId, "localhost", privateKey, userHandle, /*signCount=*/0); Assertions.assertThrows(InvalidArgumentException.class, () -> authenticator.addCredential(credential)); } @Test @Disabled("A fix was implemented and will be available in Selenium 4.34.") public void testCreateAndAddNonResidentialKey() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .setHasResidentKey(false); VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options); byte[] credentialId = {1, 2, 3, 4}; Credential nonResidentCredential = Credential.createNonResidentCredential( credentialId, "localhost", ec256PrivateKey, /*signCount=*/0); authenticator.addCredential(nonResidentCredential); List<Credential> credentialList = authenticator.getCredentials(); Assertions.assertEquals(1, credentialList.size()); Credential credential = credentialList.get(0); Assertions.assertArrayEquals(credentialId, credential.getId()); } @Test public void testGetCredential() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2) .setHasResidentKey(true) .setHasUserVerification(true) .setIsUserVerified(true); VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options); byte[] credentialId = {1, 2, 3, 4}; byte[] userHandle = {1}; Credential residentCredential = Credential.createResidentCredential( credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0); authenticator.addCredential(residentCredential); List<Credential> credentialList = authenticator.getCredentials(); Assertions.assertEquals(1, credentialList.size()); Credential credential = credentialList.get(0); Assertions.assertArrayEquals(credentialId, credential.getId()); Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded()); } @Test public void testRemoveCredential() { VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions()); byte[] credentialId = {1, 2, 3, 4}; Credential credential = Credential.createNonResidentCredential( credentialId, "localhost", rsaPrivateKey, 0); authenticator.addCredential(credential); authenticator.removeCredential(credentialId); Assertions.assertEquals(0, authenticator.getCredentials().size()); } @Test public void testRemoveAllCredentials() { VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions()); byte[] credentialId = {1, 2, 3, 4}; Credential residentCredential = Credential.createNonResidentCredential( credentialId, "localhost", rsaPrivateKey, /*signCount=*/0); authenticator.addCredential(residentCredential); authenticator.removeAllCredentials(); Assertions.assertEquals(0, authenticator.getCredentials().size()); } @Test public void testSetUserVerified() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setIsUserVerified(true); Assertions.assertTrue((boolean) options.toMap().get("isUserVerified")); } }
driver.remove_credential(credential.id)
examples/python/tests/interactions/test_virtual_authenticator.py
import pytest from base64 import urlsafe_b64decode, urlsafe_b64encode from selenium.common.exceptions import InvalidArgumentException from selenium.webdriver.chrome.webdriver import WebDriver from selenium.webdriver.common.virtual_authenticator import ( Credential, VirtualAuthenticatorOptions, ) BASE64__ENCODED_PK = ''' MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0 +j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM 8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD /Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ 5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8 K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa 9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H BYGpI8g== ''' @pytest.fixture(scope="module", autouse=True) def driver(): yield WebDriver() def test_virtual_authenticator_options(): options = VirtualAuthenticatorOptions() options.is_user_verified = True options.has_user_verification = True options.is_user_consenting = True options.transport = VirtualAuthenticatorOptions.Transport.USB options.protocol = VirtualAuthenticatorOptions.Protocol.U2F options.has_resident_key = False assert len(options.to_dict()) == 6 def test_add_authenticator(driver): # Create virtual authenticator options options = VirtualAuthenticatorOptions() options.protocol = VirtualAuthenticatorOptions.Protocol.U2F options.has_resident_key = False # Register a virtual authenticator driver.add_virtual_authenticator(options) # Get list of credentials credential_list = driver.get_credentials() assert len(credential_list) == 0 def test_remove_authenticator(driver): # Create default virtual authenticator option options = VirtualAuthenticatorOptions() # Register a virtual authenticator driver.add_virtual_authenticator(options) # Remove virtual authenticator driver.remove_virtual_authenticator() assert driver.virtual_authenticator_id is None def test_create_and_add_resident_key(driver): # Create virtual authenticator options options = VirtualAuthenticatorOptions() options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2 options.has_resident_key = True options.has_user_verification = True options.is_user_verified = True # Register a virtual authenticator driver.add_virtual_authenticator(options) # parameters for Resident Credential credential_id = bytearray({1, 2, 3, 4}) rp_id = "localhost" user_handle = bytearray({1}) privatekey = urlsafe_b64decode(BASE64__ENCODED_PK) sign_count = 0 # create a resident credential using above parameters resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count) # add the credential created to virtual authenticator driver.add_credential(resident_credential) # get list of all the registered credentials credential_list = driver.get_credentials() assert len(credential_list) == 1 def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver): # Create virtual authenticator options options = VirtualAuthenticatorOptions() options.protocol = VirtualAuthenticatorOptions.Protocol.U2F options.has_resident_key = False # Register a virtual authenticator driver.add_virtual_authenticator(options) # parameters for Resident Credential credential_id = bytearray({1, 2, 3, 4}) rp_id = "localhost" user_handle = bytearray({1}) privatekey = urlsafe_b64decode(BASE64__ENCODED_PK) sign_count = 0 # create a resident credential using above parameters credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count) # Expect InvalidArgumentException with pytest.raises(InvalidArgumentException): driver.add_credential(credential) def test_create_and_add_non_resident_key(driver): # Create virtual authenticator options options = VirtualAuthenticatorOptions() options.protocol = VirtualAuthenticatorOptions.Protocol.U2F options.has_resident_key = False # Register a virtual authenticator driver.add_virtual_authenticator(options) # parameters for Non Resident Credential credential_id = bytearray({1, 2, 3, 4}) rp_id = "localhost" privatekey = urlsafe_b64decode(BASE64__ENCODED_PK) sign_count = 0 # create a non resident credential using above parameters credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count) # add the credential created to virtual authenticator driver.add_credential(credential) # get list of all the registered credentials credential_list = driver.get_credentials() assert len(credential_list) == 1 def test_get_credential(driver): # Create virtual authenticator options options = VirtualAuthenticatorOptions() options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2 options.has_resident_key = True options.has_user_verfied = True options.is_user_verified = True # Register a virtual authenticator driver.add_virtual_authenticator(options) # parameters for Resident Credential credential_id = bytearray({1, 2, 3, 4}) rp_id = "localhost" user_handle = bytearray({1}) privatekey = urlsafe_b64decode(BASE64__ENCODED_PK) sign_count = 0 # create a resident credential using above parameters credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count) # add the credential created to virtual authenticator driver.add_credential(credential) # get list of all the registered credentials credential_list = driver.get_credentials() assert len(credential_list) == 1 assert credential_list[0].id == urlsafe_b64encode(credential_id).decode() def test_remove_credential(driver): # Create default virtual authenticator options options = VirtualAuthenticatorOptions() # Register a virtual authenticator driver.add_virtual_authenticator(options) # parameters for Non Resident Credential credential_id = bytearray({1, 2, 3, 4}) rp_id = "localhost" privatekey = urlsafe_b64decode(BASE64__ENCODED_PK) sign_count = 0 # create a non resident credential using above parameters credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count) # add the credential created to virtual authenticator driver.add_credential(credential) # remove the credential created from virtual authenticator driver.remove_credential(credential.id) # credential can also be removed using Byte Array # driver.remove_credential(credential_id) assert len(driver.get_credentials()) == 0 def test_remove_all_credentials(driver): # Create default virtual authenticator options options = VirtualAuthenticatorOptions() options.has_resident_key = True # Register a virtual authenticator driver.add_virtual_authenticator(options) # parameters for Resident Credential credential_id = bytearray({1, 2, 3, 4}) rp_id = "localhost" user_handle = bytearray({1}) privatekey = urlsafe_b64decode(BASE64__ENCODED_PK) sign_count = 0 # create a resident credential using above parameters resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count) # add the credential created to virtual authenticator driver.add_credential(resident_credential) # remove all credentials in virtual authenticator driver.remove_all_credentials() assert len(driver.get_credentials()) == 0 def test_set_user_verified(): # Create virtual authenticator options options = VirtualAuthenticatorOptions() options.is_user_verified = True assert options.to_dict().get("isUserVerified") is True
Remove All Credentials
Remove todas as credenciais do autenticador.
@Test public void testRemoveAllCredentials() { VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions()); byte[] credentialId = {1, 2, 3, 4}; Credential residentCredential = Credential.createNonResidentCredential( credentialId, "localhost", rsaPrivateKey, /*signCount=*/0); authenticator.addCredential(residentCredential);
examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java
package dev.selenium.interactions; import dev.selenium.BaseChromeTest; import java.security.spec.PKCS8EncodedKeySpec; import java.util.Base64; import java.util.List; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.openqa.selenium.InvalidArgumentException; import org.openqa.selenium.virtualauthenticator.Credential; import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator; import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator; import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions; public class VirtualAuthenticatorTest extends BaseChromeTest { /** * A pkcs#8 encoded encrypted RSA private key as a base64url string. */ private final static String base64EncodedRsaPK = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB" + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi" + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P" + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui" + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/" + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib" + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko" + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC" + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK" + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63" + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl" + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V" + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B" + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw" + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI" + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB" + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g=="; private final static PKCS8EncodedKeySpec rsaPrivateKey = new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK)); // A pkcs#8 encoded unencrypted EC256 private key as a base64url string. String base64EncodedEC256PK = "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB"; PKCS8EncodedKeySpec ec256PrivateKey = new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK)); @Test public void testVirtualOptions() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setIsUserVerified(true) .setHasUserVerification(true) .setIsUserConsenting(true) .setTransport(VirtualAuthenticatorOptions.Transport.USB) .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .setHasResidentKey(false); Assertions.assertEquals(6, options.toMap().size()); } @Test public void testCreateAuthenticator() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .setHasResidentKey(false); VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options); List<Credential> credentialList = authenticator.getCredentials(); Assertions.assertEquals(0, credentialList.size()); } @Test public void testRemoveAuthenticator() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions(); VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options); ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator); Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials); } @Test public void testCreateAndAddResidentialKey() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2) .setHasResidentKey(true) .setHasUserVerification(true) .setIsUserVerified(true); VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options); byte[] credentialId = {1, 2, 3, 4}; byte[] userHandle = {1}; Credential residentCredential = Credential.createResidentCredential( credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0); authenticator.addCredential(residentCredential); List<Credential> credentialList = authenticator.getCredentials(); Assertions.assertEquals(1, credentialList.size()); Credential credential = credentialList.get(0); Assertions.assertArrayEquals(credentialId, credential.getId()); } @Test public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .setHasResidentKey(true); VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options); PKCS8EncodedKeySpec privateKey = new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK)); byte[] credentialId = {1, 2, 3, 4}; byte[] userHandle = {1}; Credential credential = Credential.createResidentCredential( credentialId, "localhost", privateKey, userHandle, /*signCount=*/0); Assertions.assertThrows(InvalidArgumentException.class, () -> authenticator.addCredential(credential)); } @Test @Disabled("A fix was implemented and will be available in Selenium 4.34.") public void testCreateAndAddNonResidentialKey() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .setHasResidentKey(false); VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options); byte[] credentialId = {1, 2, 3, 4}; Credential nonResidentCredential = Credential.createNonResidentCredential( credentialId, "localhost", ec256PrivateKey, /*signCount=*/0); authenticator.addCredential(nonResidentCredential); List<Credential> credentialList = authenticator.getCredentials(); Assertions.assertEquals(1, credentialList.size()); Credential credential = credentialList.get(0); Assertions.assertArrayEquals(credentialId, credential.getId()); } @Test public void testGetCredential() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2) .setHasResidentKey(true) .setHasUserVerification(true) .setIsUserVerified(true); VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options); byte[] credentialId = {1, 2, 3, 4}; byte[] userHandle = {1}; Credential residentCredential = Credential.createResidentCredential( credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0); authenticator.addCredential(residentCredential); List<Credential> credentialList = authenticator.getCredentials(); Assertions.assertEquals(1, credentialList.size()); Credential credential = credentialList.get(0); Assertions.assertArrayEquals(credentialId, credential.getId()); Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded()); } @Test public void testRemoveCredential() { VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions()); byte[] credentialId = {1, 2, 3, 4}; Credential credential = Credential.createNonResidentCredential( credentialId, "localhost", rsaPrivateKey, 0); authenticator.addCredential(credential); authenticator.removeCredential(credentialId); Assertions.assertEquals(0, authenticator.getCredentials().size()); } @Test public void testRemoveAllCredentials() { VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions()); byte[] credentialId = {1, 2, 3, 4}; Credential residentCredential = Credential.createNonResidentCredential( credentialId, "localhost", rsaPrivateKey, /*signCount=*/0); authenticator.addCredential(residentCredential); authenticator.removeAllCredentials(); Assertions.assertEquals(0, authenticator.getCredentials().size()); } @Test public void testSetUserVerified() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setIsUserVerified(true); Assertions.assertTrue((boolean) options.toMap().get("isUserVerified")); } }
((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions()); byte[] credentialId = { 1, 2, 3, 4 }; Credential nonResidentCredential = Credential.CreateNonResidentCredential( credentialId, "localhost", base64EncodedEC256PK, 0); ((WebDriver)driver).AddCredential(nonResidentCredential); ((WebDriver)driver).RemoveAllCredentials();
examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs
using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.IdentityModel.Tokens; using OpenQA.Selenium; using OpenQA.Selenium.VirtualAuth; using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions; using System.Collections.Generic; using System; namespace SeleniumDocs.VirtualAuthentication { [TestClass] public class VirtualAuthenticatorTest : BaseChromeTest { //A pkcs#8 encoded encrypted RSA private key as a base64 string. private static string base64EncodedRSAPK = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB" + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi" + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P" + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui" + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/" + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib" + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko" + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC" + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK" + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63" + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl" + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V" + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B" + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw" + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI" + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB" + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g=="; private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK); private string base64EncodedPK = Base64UrlEncoder.Encode(bytes); // A pkcs#8 encoded unencrypted EC256 private key as a base64url string. private string base64EncodedEC256PK = "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB"; [TestMethod] public void VirtualOptionsShouldAllowSettingOptions() { // Create virtual authenticator options VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetIsUserVerified(true) .SetHasUserVerification(true) .SetIsUserConsenting(true) .SetTransport(VirtualAuthenticatorOptions.Transport.USB) .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .SetHasResidentKey(false); Assert.AreEqual(6, options.ToDictionary().Count); } [TestMethod] public void ShouldBeAbleToCreateAuthenticator() { // Create virtual authenticator options VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .SetHasResidentKey(false); // Register a virtual authenticator ((WebDriver)driver).AddVirtualAuthenticator(options); List<Credential> credentialList = ((WebDriver)driver).GetCredentials(); Assert.AreEqual(0, credentialList.Count); } [TestMethod] public void ShouldBeAbleToRemoveAuthenticator() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .SetHasResidentKey(false); String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options); ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId); // Since the authenticator was removed, any operation using it will throw an error Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials()); } [TestMethod] public void ShouldBeAbleToCreateAndAddResidentialKey() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetProtocol(Protocol.CTAP2) .SetHasResidentKey(true) .SetHasUserVerification(true) .SetIsUserVerified(true); ((WebDriver)driver).AddVirtualAuthenticator(options); byte[] credentialId = { 1, 2, 3, 4 }; byte[] userHandle = { 1 }; Credential residentCredential = Credential.CreateResidentCredential( credentialId, "localhost", base64EncodedPK, userHandle, 0); ((WebDriver)driver).AddCredential(residentCredential); List<Credential> credentialList = ((WebDriver)driver).GetCredentials(); Assert.AreEqual(1, credentialList.Count); Credential credential = credentialList[0]; CollectionAssert.AreEqual(credentialId, credential.Id); } [TestMethod] public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .SetHasResidentKey(true); ((WebDriver)driver).AddVirtualAuthenticator(options); byte[] credentialId = { 1, 2, 3, 4 }; byte[] userHandle = { 1 }; Credential credential = Credential.CreateResidentCredential( credentialId, "localhost", base64EncodedEC256PK, userHandle, 0); Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential)); } [TestMethod] public void ShouldBeAbleToCreateAndAddNonResidentKey() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .SetHasResidentKey(false); ((WebDriver)driver).AddVirtualAuthenticator(options); byte[] credentialId = { 1, 2, 3, 4 }; Credential nonResidentCredential = Credential.CreateNonResidentCredential( credentialId, "localhost", base64EncodedEC256PK, 0); ((WebDriver)driver).AddCredential(nonResidentCredential); List<Credential> credentialList = ((WebDriver)driver).GetCredentials(); Assert.AreEqual(1, credentialList.Count); Credential credential = credentialList[0]; CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id); } [TestMethod] public void ShouldBeAbleToGetCredential() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetProtocol(Protocol.CTAP2) .SetHasResidentKey(true) .SetHasUserVerification(true) .SetIsUserVerified(true); ((WebDriver)driver).AddVirtualAuthenticator(options); byte[] credentialId = { 1, 2, 3, 4 }; byte[] userHandle = { 1 }; Credential residentCredential = Credential.CreateResidentCredential( credentialId, "localhost", base64EncodedPK, userHandle, 0); ((WebDriver)driver).AddCredential(residentCredential); List<Credential> credentialList = ((WebDriver)driver).GetCredentials(); Assert.AreEqual(1, credentialList.Count); Credential credential = credentialList[0]; CollectionAssert.AreEqual(credentialId, residentCredential.Id); Assert.AreEqual(base64EncodedPK, credential.PrivateKey); } [TestMethod] public void ShouldBeAbleToRemoveCredential() { ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions()); byte[] credentialId = { 1, 2, 3, 4 }; Credential nonResidentCredential = Credential.CreateNonResidentCredential( credentialId, "localhost", base64EncodedEC256PK, 0); ((WebDriver)driver).AddCredential(nonResidentCredential); ((WebDriver)driver).RemoveCredential(credentialId); Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count); } [TestMethod] public void ShouldBeAbleToRemoveAllCredentias() { ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions()); byte[] credentialId = { 1, 2, 3, 4 }; Credential nonResidentCredential = Credential.CreateNonResidentCredential( credentialId, "localhost", base64EncodedEC256PK, 0); ((WebDriver)driver).AddCredential(nonResidentCredential); ((WebDriver)driver).RemoveAllCredentials(); Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count); } [TestMethod] public void ShouldBeSetVerifiedOption() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetIsUserVerified(true); Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]); } } }
driver.remove_all_credentials()
examples/python/tests/interactions/test_virtual_authenticator.py
import pytest from base64 import urlsafe_b64decode, urlsafe_b64encode from selenium.common.exceptions import InvalidArgumentException from selenium.webdriver.chrome.webdriver import WebDriver from selenium.webdriver.common.virtual_authenticator import ( Credential, VirtualAuthenticatorOptions, ) BASE64__ENCODED_PK = ''' MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0 +j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM 8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD /Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ 5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8 K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa 9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H BYGpI8g== ''' @pytest.fixture(scope="module", autouse=True) def driver(): yield WebDriver() def test_virtual_authenticator_options(): options = VirtualAuthenticatorOptions() options.is_user_verified = True options.has_user_verification = True options.is_user_consenting = True options.transport = VirtualAuthenticatorOptions.Transport.USB options.protocol = VirtualAuthenticatorOptions.Protocol.U2F options.has_resident_key = False assert len(options.to_dict()) == 6 def test_add_authenticator(driver): # Create virtual authenticator options options = VirtualAuthenticatorOptions() options.protocol = VirtualAuthenticatorOptions.Protocol.U2F options.has_resident_key = False # Register a virtual authenticator driver.add_virtual_authenticator(options) # Get list of credentials credential_list = driver.get_credentials() assert len(credential_list) == 0 def test_remove_authenticator(driver): # Create default virtual authenticator option options = VirtualAuthenticatorOptions() # Register a virtual authenticator driver.add_virtual_authenticator(options) # Remove virtual authenticator driver.remove_virtual_authenticator() assert driver.virtual_authenticator_id is None def test_create_and_add_resident_key(driver): # Create virtual authenticator options options = VirtualAuthenticatorOptions() options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2 options.has_resident_key = True options.has_user_verification = True options.is_user_verified = True # Register a virtual authenticator driver.add_virtual_authenticator(options) # parameters for Resident Credential credential_id = bytearray({1, 2, 3, 4}) rp_id = "localhost" user_handle = bytearray({1}) privatekey = urlsafe_b64decode(BASE64__ENCODED_PK) sign_count = 0 # create a resident credential using above parameters resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count) # add the credential created to virtual authenticator driver.add_credential(resident_credential) # get list of all the registered credentials credential_list = driver.get_credentials() assert len(credential_list) == 1 def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver): # Create virtual authenticator options options = VirtualAuthenticatorOptions() options.protocol = VirtualAuthenticatorOptions.Protocol.U2F options.has_resident_key = False # Register a virtual authenticator driver.add_virtual_authenticator(options) # parameters for Resident Credential credential_id = bytearray({1, 2, 3, 4}) rp_id = "localhost" user_handle = bytearray({1}) privatekey = urlsafe_b64decode(BASE64__ENCODED_PK) sign_count = 0 # create a resident credential using above parameters credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count) # Expect InvalidArgumentException with pytest.raises(InvalidArgumentException): driver.add_credential(credential) def test_create_and_add_non_resident_key(driver): # Create virtual authenticator options options = VirtualAuthenticatorOptions() options.protocol = VirtualAuthenticatorOptions.Protocol.U2F options.has_resident_key = False # Register a virtual authenticator driver.add_virtual_authenticator(options) # parameters for Non Resident Credential credential_id = bytearray({1, 2, 3, 4}) rp_id = "localhost" privatekey = urlsafe_b64decode(BASE64__ENCODED_PK) sign_count = 0 # create a non resident credential using above parameters credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count) # add the credential created to virtual authenticator driver.add_credential(credential) # get list of all the registered credentials credential_list = driver.get_credentials() assert len(credential_list) == 1 def test_get_credential(driver): # Create virtual authenticator options options = VirtualAuthenticatorOptions() options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2 options.has_resident_key = True options.has_user_verfied = True options.is_user_verified = True # Register a virtual authenticator driver.add_virtual_authenticator(options) # parameters for Resident Credential credential_id = bytearray({1, 2, 3, 4}) rp_id = "localhost" user_handle = bytearray({1}) privatekey = urlsafe_b64decode(BASE64__ENCODED_PK) sign_count = 0 # create a resident credential using above parameters credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count) # add the credential created to virtual authenticator driver.add_credential(credential) # get list of all the registered credentials credential_list = driver.get_credentials() assert len(credential_list) == 1 assert credential_list[0].id == urlsafe_b64encode(credential_id).decode() def test_remove_credential(driver): # Create default virtual authenticator options options = VirtualAuthenticatorOptions() # Register a virtual authenticator driver.add_virtual_authenticator(options) # parameters for Non Resident Credential credential_id = bytearray({1, 2, 3, 4}) rp_id = "localhost" privatekey = urlsafe_b64decode(BASE64__ENCODED_PK) sign_count = 0 # create a non resident credential using above parameters credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count) # add the credential created to virtual authenticator driver.add_credential(credential) # remove the credential created from virtual authenticator driver.remove_credential(credential.id) # credential can also be removed using Byte Array # driver.remove_credential(credential_id) assert len(driver.get_credentials()) == 0 def test_remove_all_credentials(driver): # Create default virtual authenticator options options = VirtualAuthenticatorOptions() options.has_resident_key = True # Register a virtual authenticator driver.add_virtual_authenticator(options) # parameters for Resident Credential credential_id = bytearray({1, 2, 3, 4}) rp_id = "localhost" user_handle = bytearray({1}) privatekey = urlsafe_b64decode(BASE64__ENCODED_PK) sign_count = 0 # create a resident credential using above parameters resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count) # add the credential created to virtual authenticator driver.add_credential(resident_credential) # remove all credentials in virtual authenticator driver.remove_all_credentials() assert len(driver.get_credentials()) == 0 def test_set_user_verified(): # Create virtual authenticator options options = VirtualAuthenticatorOptions() options.is_user_verified = True assert options.to_dict().get("isUserVerified") is True
await driver.addVirtualAuthenticator(options); let nonResidentCredential = new Credential().createNonResidentCredential( new Uint8Array([1, 2, 3, 4]), 'localhost', Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'), 0); await driver.addCredential(nonResidentCredential); await driver.removeAllCredentials();
examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js
const { Builder} = require("selenium-webdriver"); const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator"); const assert = require('assert') const { InvalidArgumentError } = require("selenium-webdriver/lib/error"); describe('Virtual authenticator', function() { const BASE64_ENCODED_PK = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" + "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" + "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" + "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" + "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" + "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" + "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" + "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" + "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" + "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" + "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" + "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" + "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" + "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" + "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" + "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" + "BYGpI8g=="; const base64EncodedPK = "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB"; let options; let driver; before(async function() { options = new VirtualAuthenticatorOptions(); driver = await new Builder().forBrowser('chrome').build(); }); after(async() => await driver.quit()); function arraysEqual(array1, array2) { return (array1.length === array2.length && array1.every((item) => array2.includes(item)) && array2.every((item) => array1.includes(item))); } it('Register a virtual authenticator', async function() { options.setProtocol(Protocol['U2F']); options.setHasResidentKey(false); // Register a virtual authenticator await driver.addVirtualAuthenticator(options); let credentialList = await driver.getCredentials(); assert.equal(0, credentialList.length); }); it('Remove authenticator', async function() { await driver.addVirtualAuthenticator(options); await driver.removeVirtualAuthenticator(); // Since the authenticator was removed, any operation using it will throw an error try { await driver.getCredentials() } catch (e) { if (e instanceof InvalidArgumentError) { assert(true) } else { assert(false) } } }); it('Createa and add residential key', async function() { options.setProtocol(Protocol['CTAP2']); options.setHasResidentKey(true); options.setHasUserVerification(true); options.setIsUserVerified(true); await driver.addVirtualAuthenticator(options); let residentCredential = new Credential().createResidentCredential( new Uint8Array([1, 2, 3, 4]), 'localhost', new Uint8Array([1]), Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'), 0); await driver.addCredential(residentCredential); let credentialList = await driver.getCredentials(); assert.equal(1, credentialList.length); let credential_id = credentialList[0].id(); let test_id = new Uint8Array([1, 2, 3, 4]); assert(arraysEqual(credential_id, test_id)); }); it('Add resident credential not supported when authenticator uses U2F protocol', async function() { options.setProtocol(Protocol['U2F']); options.setHasResidentKey(true); await driver.addVirtualAuthenticator(options); let credential = new Credential().createResidentCredential( new Uint8Array([1, 2, 3, 4]), 'localhost', new Uint8Array([1]), Buffer.from(base64EncodedPK, 'base64').toString('binary'), 0); try { await driver.addCredential(credential) } catch (e) { if (e instanceof InvalidArgumentError) { assert(true) } else { assert(false) } } }); it('Create and add non residential key', async function() { options.setProtocol(Protocol['U2F']); options.setHasResidentKey(false); await driver.addVirtualAuthenticator(options); let nonResidentCredential = new Credential().createNonResidentCredential( new Uint8Array([1, 2, 3, 4]), 'localhost', Buffer.from(base64EncodedPK, 'base64').toString('binary'), 0); await driver.addCredential(nonResidentCredential); let credentialList = await driver.getCredentials(); assert.equal(1, credentialList.length); let credential_id = credentialList[0].id(); let test_id = new Uint8Array([1, 2, 3, 4]); assert(arraysEqual(credential_id, test_id)); }); it('Get credential', async function() { options.setProtocol(Protocol['CTAP2']); options.setHasResidentKey(true); options.setHasUserVerification(true); options.setIsUserVerified(true); await driver.addVirtualAuthenticator(options); let residentCredential = new Credential().createResidentCredential( new Uint8Array([1, 2, 3, 4]), 'localhost', new Uint8Array([1]), Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'), 0); await driver.addCredential(residentCredential); let credentialList = await driver.getCredentials(); assert.equal(1, credentialList.length); let credential_id = credentialList[0].id(); let test_id = new Uint8Array([1, 2, 3, 4]); assert(arraysEqual(credential_id, test_id)); assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64')); }); it('Remove all credentials', async function() { await driver.addVirtualAuthenticator(options); let nonResidentCredential = new Credential().createNonResidentCredential( new Uint8Array([1, 2, 3, 4]), 'localhost', Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'), 0); await driver.addCredential(nonResidentCredential); await driver.removeAllCredentials(); let credentialList = await driver.getCredentials(); assert.equal(0, credentialList.length); }); it('Set is user verified', async function() { options.setIsUserVerified(true); assert.equal(options.getIsUserVerified(), true); }); });
Set User Verified
Diz se o autenticador simulará sucesso ou falha na verificação de usuário.
@Test public void testSetUserVerified() {
examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java
package dev.selenium.interactions; import dev.selenium.BaseChromeTest; import java.security.spec.PKCS8EncodedKeySpec; import java.util.Base64; import java.util.List; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.openqa.selenium.InvalidArgumentException; import org.openqa.selenium.virtualauthenticator.Credential; import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator; import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator; import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions; public class VirtualAuthenticatorTest extends BaseChromeTest { /** * A pkcs#8 encoded encrypted RSA private key as a base64url string. */ private final static String base64EncodedRsaPK = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB" + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi" + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P" + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui" + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/" + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib" + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko" + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC" + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK" + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63" + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl" + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V" + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B" + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw" + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI" + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB" + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g=="; private final static PKCS8EncodedKeySpec rsaPrivateKey = new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK)); // A pkcs#8 encoded unencrypted EC256 private key as a base64url string. String base64EncodedEC256PK = "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB"; PKCS8EncodedKeySpec ec256PrivateKey = new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK)); @Test public void testVirtualOptions() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setIsUserVerified(true) .setHasUserVerification(true) .setIsUserConsenting(true) .setTransport(VirtualAuthenticatorOptions.Transport.USB) .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .setHasResidentKey(false); Assertions.assertEquals(6, options.toMap().size()); } @Test public void testCreateAuthenticator() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .setHasResidentKey(false); VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options); List<Credential> credentialList = authenticator.getCredentials(); Assertions.assertEquals(0, credentialList.size()); } @Test public void testRemoveAuthenticator() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions(); VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options); ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator); Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials); } @Test public void testCreateAndAddResidentialKey() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2) .setHasResidentKey(true) .setHasUserVerification(true) .setIsUserVerified(true); VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options); byte[] credentialId = {1, 2, 3, 4}; byte[] userHandle = {1}; Credential residentCredential = Credential.createResidentCredential( credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0); authenticator.addCredential(residentCredential); List<Credential> credentialList = authenticator.getCredentials(); Assertions.assertEquals(1, credentialList.size()); Credential credential = credentialList.get(0); Assertions.assertArrayEquals(credentialId, credential.getId()); } @Test public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .setHasResidentKey(true); VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options); PKCS8EncodedKeySpec privateKey = new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK)); byte[] credentialId = {1, 2, 3, 4}; byte[] userHandle = {1}; Credential credential = Credential.createResidentCredential( credentialId, "localhost", privateKey, userHandle, /*signCount=*/0); Assertions.assertThrows(InvalidArgumentException.class, () -> authenticator.addCredential(credential)); } @Test @Disabled("A fix was implemented and will be available in Selenium 4.34.") public void testCreateAndAddNonResidentialKey() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .setHasResidentKey(false); VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options); byte[] credentialId = {1, 2, 3, 4}; Credential nonResidentCredential = Credential.createNonResidentCredential( credentialId, "localhost", ec256PrivateKey, /*signCount=*/0); authenticator.addCredential(nonResidentCredential); List<Credential> credentialList = authenticator.getCredentials(); Assertions.assertEquals(1, credentialList.size()); Credential credential = credentialList.get(0); Assertions.assertArrayEquals(credentialId, credential.getId()); } @Test public void testGetCredential() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2) .setHasResidentKey(true) .setHasUserVerification(true) .setIsUserVerified(true); VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options); byte[] credentialId = {1, 2, 3, 4}; byte[] userHandle = {1}; Credential residentCredential = Credential.createResidentCredential( credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0); authenticator.addCredential(residentCredential); List<Credential> credentialList = authenticator.getCredentials(); Assertions.assertEquals(1, credentialList.size()); Credential credential = credentialList.get(0); Assertions.assertArrayEquals(credentialId, credential.getId()); Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded()); } @Test public void testRemoveCredential() { VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions()); byte[] credentialId = {1, 2, 3, 4}; Credential credential = Credential.createNonResidentCredential( credentialId, "localhost", rsaPrivateKey, 0); authenticator.addCredential(credential); authenticator.removeCredential(credentialId); Assertions.assertEquals(0, authenticator.getCredentials().size()); } @Test public void testRemoveAllCredentials() { VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions()); byte[] credentialId = {1, 2, 3, 4}; Credential residentCredential = Credential.createNonResidentCredential( credentialId, "localhost", rsaPrivateKey, /*signCount=*/0); authenticator.addCredential(residentCredential); authenticator.removeAllCredentials(); Assertions.assertEquals(0, authenticator.getCredentials().size()); } @Test public void testSetUserVerified() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .setIsUserVerified(true); Assertions.assertTrue((boolean) options.toMap().get("isUserVerified")); } }
VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetIsUserVerified(true);
examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs
using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.IdentityModel.Tokens; using OpenQA.Selenium; using OpenQA.Selenium.VirtualAuth; using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions; using System.Collections.Generic; using System; namespace SeleniumDocs.VirtualAuthentication { [TestClass] public class VirtualAuthenticatorTest : BaseChromeTest { //A pkcs#8 encoded encrypted RSA private key as a base64 string. private static string base64EncodedRSAPK = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB" + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi" + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P" + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui" + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/" + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib" + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko" + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC" + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK" + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63" + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl" + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V" + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B" + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw" + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI" + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB" + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g=="; private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK); private string base64EncodedPK = Base64UrlEncoder.Encode(bytes); // A pkcs#8 encoded unencrypted EC256 private key as a base64url string. private string base64EncodedEC256PK = "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB"; [TestMethod] public void VirtualOptionsShouldAllowSettingOptions() { // Create virtual authenticator options VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetIsUserVerified(true) .SetHasUserVerification(true) .SetIsUserConsenting(true) .SetTransport(VirtualAuthenticatorOptions.Transport.USB) .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .SetHasResidentKey(false); Assert.AreEqual(6, options.ToDictionary().Count); } [TestMethod] public void ShouldBeAbleToCreateAuthenticator() { // Create virtual authenticator options VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .SetHasResidentKey(false); // Register a virtual authenticator ((WebDriver)driver).AddVirtualAuthenticator(options); List<Credential> credentialList = ((WebDriver)driver).GetCredentials(); Assert.AreEqual(0, credentialList.Count); } [TestMethod] public void ShouldBeAbleToRemoveAuthenticator() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .SetHasResidentKey(false); String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options); ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId); // Since the authenticator was removed, any operation using it will throw an error Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials()); } [TestMethod] public void ShouldBeAbleToCreateAndAddResidentialKey() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetProtocol(Protocol.CTAP2) .SetHasResidentKey(true) .SetHasUserVerification(true) .SetIsUserVerified(true); ((WebDriver)driver).AddVirtualAuthenticator(options); byte[] credentialId = { 1, 2, 3, 4 }; byte[] userHandle = { 1 }; Credential residentCredential = Credential.CreateResidentCredential( credentialId, "localhost", base64EncodedPK, userHandle, 0); ((WebDriver)driver).AddCredential(residentCredential); List<Credential> credentialList = ((WebDriver)driver).GetCredentials(); Assert.AreEqual(1, credentialList.Count); Credential credential = credentialList[0]; CollectionAssert.AreEqual(credentialId, credential.Id); } [TestMethod] public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .SetHasResidentKey(true); ((WebDriver)driver).AddVirtualAuthenticator(options); byte[] credentialId = { 1, 2, 3, 4 }; byte[] userHandle = { 1 }; Credential credential = Credential.CreateResidentCredential( credentialId, "localhost", base64EncodedEC256PK, userHandle, 0); Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential)); } [TestMethod] public void ShouldBeAbleToCreateAndAddNonResidentKey() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F) .SetHasResidentKey(false); ((WebDriver)driver).AddVirtualAuthenticator(options); byte[] credentialId = { 1, 2, 3, 4 }; Credential nonResidentCredential = Credential.CreateNonResidentCredential( credentialId, "localhost", base64EncodedEC256PK, 0); ((WebDriver)driver).AddCredential(nonResidentCredential); List<Credential> credentialList = ((WebDriver)driver).GetCredentials(); Assert.AreEqual(1, credentialList.Count); Credential credential = credentialList[0]; CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id); } [TestMethod] public void ShouldBeAbleToGetCredential() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetProtocol(Protocol.CTAP2) .SetHasResidentKey(true) .SetHasUserVerification(true) .SetIsUserVerified(true); ((WebDriver)driver).AddVirtualAuthenticator(options); byte[] credentialId = { 1, 2, 3, 4 }; byte[] userHandle = { 1 }; Credential residentCredential = Credential.CreateResidentCredential( credentialId, "localhost", base64EncodedPK, userHandle, 0); ((WebDriver)driver).AddCredential(residentCredential); List<Credential> credentialList = ((WebDriver)driver).GetCredentials(); Assert.AreEqual(1, credentialList.Count); Credential credential = credentialList[0]; CollectionAssert.AreEqual(credentialId, residentCredential.Id); Assert.AreEqual(base64EncodedPK, credential.PrivateKey); } [TestMethod] public void ShouldBeAbleToRemoveCredential() { ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions()); byte[] credentialId = { 1, 2, 3, 4 }; Credential nonResidentCredential = Credential.CreateNonResidentCredential( credentialId, "localhost", base64EncodedEC256PK, 0); ((WebDriver)driver).AddCredential(nonResidentCredential); ((WebDriver)driver).RemoveCredential(credentialId); Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count); } [TestMethod] public void ShouldBeAbleToRemoveAllCredentias() { ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions()); byte[] credentialId = { 1, 2, 3, 4 }; Credential nonResidentCredential = Credential.CreateNonResidentCredential( credentialId, "localhost", base64EncodedEC256PK, 0); ((WebDriver)driver).AddCredential(nonResidentCredential); ((WebDriver)driver).RemoveAllCredentials(); Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count); } [TestMethod] public void ShouldBeSetVerifiedOption() { VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions() .SetIsUserVerified(true); Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]); } } }
# Create virtual authenticator options options = VirtualAuthenticatorOptions() options.is_user_verified = True
examples/python/tests/interactions/test_virtual_authenticator.py
import pytest from base64 import urlsafe_b64decode, urlsafe_b64encode from selenium.common.exceptions import InvalidArgumentException from selenium.webdriver.chrome.webdriver import WebDriver from selenium.webdriver.common.virtual_authenticator import ( Credential, VirtualAuthenticatorOptions, ) BASE64__ENCODED_PK = ''' MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0 +j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM 8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD /Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ 5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8 K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa 9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H BYGpI8g== ''' @pytest.fixture(scope="module", autouse=True) def driver(): yield WebDriver() def test_virtual_authenticator_options(): options = VirtualAuthenticatorOptions() options.is_user_verified = True options.has_user_verification = True options.is_user_consenting = True options.transport = VirtualAuthenticatorOptions.Transport.USB options.protocol = VirtualAuthenticatorOptions.Protocol.U2F options.has_resident_key = False assert len(options.to_dict()) == 6 def test_add_authenticator(driver): # Create virtual authenticator options options = VirtualAuthenticatorOptions() options.protocol = VirtualAuthenticatorOptions.Protocol.U2F options.has_resident_key = False # Register a virtual authenticator driver.add_virtual_authenticator(options) # Get list of credentials credential_list = driver.get_credentials() assert len(credential_list) == 0 def test_remove_authenticator(driver): # Create default virtual authenticator option options = VirtualAuthenticatorOptions() # Register a virtual authenticator driver.add_virtual_authenticator(options) # Remove virtual authenticator driver.remove_virtual_authenticator() assert driver.virtual_authenticator_id is None def test_create_and_add_resident_key(driver): # Create virtual authenticator options options = VirtualAuthenticatorOptions() options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2 options.has_resident_key = True options.has_user_verification = True options.is_user_verified = True # Register a virtual authenticator driver.add_virtual_authenticator(options) # parameters for Resident Credential credential_id = bytearray({1, 2, 3, 4}) rp_id = "localhost" user_handle = bytearray({1}) privatekey = urlsafe_b64decode(BASE64__ENCODED_PK) sign_count = 0 # create a resident credential using above parameters resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count) # add the credential created to virtual authenticator driver.add_credential(resident_credential) # get list of all the registered credentials credential_list = driver.get_credentials() assert len(credential_list) == 1 def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver): # Create virtual authenticator options options = VirtualAuthenticatorOptions() options.protocol = VirtualAuthenticatorOptions.Protocol.U2F options.has_resident_key = False # Register a virtual authenticator driver.add_virtual_authenticator(options) # parameters for Resident Credential credential_id = bytearray({1, 2, 3, 4}) rp_id = "localhost" user_handle = bytearray({1}) privatekey = urlsafe_b64decode(BASE64__ENCODED_PK) sign_count = 0 # create a resident credential using above parameters credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count) # Expect InvalidArgumentException with pytest.raises(InvalidArgumentException): driver.add_credential(credential) def test_create_and_add_non_resident_key(driver): # Create virtual authenticator options options = VirtualAuthenticatorOptions() options.protocol = VirtualAuthenticatorOptions.Protocol.U2F options.has_resident_key = False # Register a virtual authenticator driver.add_virtual_authenticator(options) # parameters for Non Resident Credential credential_id = bytearray({1, 2, 3, 4}) rp_id = "localhost" privatekey = urlsafe_b64decode(BASE64__ENCODED_PK) sign_count = 0 # create a non resident credential using above parameters credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count) # add the credential created to virtual authenticator driver.add_credential(credential) # get list of all the registered credentials credential_list = driver.get_credentials() assert len(credential_list) == 1 def test_get_credential(driver): # Create virtual authenticator options options = VirtualAuthenticatorOptions() options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2 options.has_resident_key = True options.has_user_verfied = True options.is_user_verified = True # Register a virtual authenticator driver.add_virtual_authenticator(options) # parameters for Resident Credential credential_id = bytearray({1, 2, 3, 4}) rp_id = "localhost" user_handle = bytearray({1}) privatekey = urlsafe_b64decode(BASE64__ENCODED_PK) sign_count = 0 # create a resident credential using above parameters credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count) # add the credential created to virtual authenticator driver.add_credential(credential) # get list of all the registered credentials credential_list = driver.get_credentials() assert len(credential_list) == 1 assert credential_list[0].id == urlsafe_b64encode(credential_id).decode() def test_remove_credential(driver): # Create default virtual authenticator options options = VirtualAuthenticatorOptions() # Register a virtual authenticator driver.add_virtual_authenticator(options) # parameters for Non Resident Credential credential_id = bytearray({1, 2, 3, 4}) rp_id = "localhost" privatekey = urlsafe_b64decode(BASE64__ENCODED_PK) sign_count = 0 # create a non resident credential using above parameters credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count) # add the credential created to virtual authenticator driver.add_credential(credential) # remove the credential created from virtual authenticator driver.remove_credential(credential.id) # credential can also be removed using Byte Array # driver.remove_credential(credential_id) assert len(driver.get_credentials()) == 0 def test_remove_all_credentials(driver): # Create default virtual authenticator options options = VirtualAuthenticatorOptions() options.has_resident_key = True # Register a virtual authenticator driver.add_virtual_authenticator(options) # parameters for Resident Credential credential_id = bytearray({1, 2, 3, 4}) rp_id = "localhost" user_handle = bytearray({1}) privatekey = urlsafe_b64decode(BASE64__ENCODED_PK) sign_count = 0 # create a resident credential using above parameters resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count) # add the credential created to virtual authenticator driver.add_credential(resident_credential) # remove all credentials in virtual authenticator driver.remove_all_credentials() assert len(driver.get_credentials()) == 0 def test_set_user_verified(): # Create virtual authenticator options options = VirtualAuthenticatorOptions() options.is_user_verified = True assert options.to_dict().get("isUserVerified") is True
options.setIsUserVerified(true);
examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js
const { Builder} = require("selenium-webdriver"); const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator"); const assert = require('assert') const { InvalidArgumentError } = require("selenium-webdriver/lib/error"); describe('Virtual authenticator', function() { const BASE64_ENCODED_PK = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" + "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" + "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" + "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" + "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" + "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" + "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" + "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" + "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" + "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" + "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" + "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" + "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" + "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" + "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" + "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" + "BYGpI8g=="; const base64EncodedPK = "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB"; let options; let driver; before(async function() { options = new VirtualAuthenticatorOptions(); driver = await new Builder().forBrowser('chrome').build(); }); after(async() => await driver.quit()); function arraysEqual(array1, array2) { return (array1.length === array2.length && array1.every((item) => array2.includes(item)) && array2.every((item) => array1.includes(item))); } it('Register a virtual authenticator', async function() { options.setProtocol(Protocol['U2F']); options.setHasResidentKey(false); // Register a virtual authenticator await driver.addVirtualAuthenticator(options); let credentialList = await driver.getCredentials(); assert.equal(0, credentialList.length); }); it('Remove authenticator', async function() { await driver.addVirtualAuthenticator(options); await driver.removeVirtualAuthenticator(); // Since the authenticator was removed, any operation using it will throw an error try { await driver.getCredentials() } catch (e) { if (e instanceof InvalidArgumentError) { assert(true) } else { assert(false) } } }); it('Createa and add residential key', async function() { options.setProtocol(Protocol['CTAP2']); options.setHasResidentKey(true); options.setHasUserVerification(true); options.setIsUserVerified(true); await driver.addVirtualAuthenticator(options); let residentCredential = new Credential().createResidentCredential( new Uint8Array([1, 2, 3, 4]), 'localhost', new Uint8Array([1]), Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'), 0); await driver.addCredential(residentCredential); let credentialList = await driver.getCredentials(); assert.equal(1, credentialList.length); let credential_id = credentialList[0].id(); let test_id = new Uint8Array([1, 2, 3, 4]); assert(arraysEqual(credential_id, test_id)); }); it('Add resident credential not supported when authenticator uses U2F protocol', async function() { options.setProtocol(Protocol['U2F']); options.setHasResidentKey(true); await driver.addVirtualAuthenticator(options); let credential = new Credential().createResidentCredential( new Uint8Array([1, 2, 3, 4]), 'localhost', new Uint8Array([1]), Buffer.from(base64EncodedPK, 'base64').toString('binary'), 0); try { await driver.addCredential(credential) } catch (e) { if (e instanceof InvalidArgumentError) { assert(true) } else { assert(false) } } }); it('Create and add non residential key', async function() { options.setProtocol(Protocol['U2F']); options.setHasResidentKey(false); await driver.addVirtualAuthenticator(options); let nonResidentCredential = new Credential().createNonResidentCredential( new Uint8Array([1, 2, 3, 4]), 'localhost', Buffer.from(base64EncodedPK, 'base64').toString('binary'), 0); await driver.addCredential(nonResidentCredential); let credentialList = await driver.getCredentials(); assert.equal(1, credentialList.length); let credential_id = credentialList[0].id(); let test_id = new Uint8Array([1, 2, 3, 4]); assert(arraysEqual(credential_id, test_id)); }); it('Get credential', async function() { options.setProtocol(Protocol['CTAP2']); options.setHasResidentKey(true); options.setHasUserVerification(true); options.setIsUserVerified(true); await driver.addVirtualAuthenticator(options); let residentCredential = new Credential().createResidentCredential( new Uint8Array([1, 2, 3, 4]), 'localhost', new Uint8Array([1]), Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'), 0); await driver.addCredential(residentCredential); let credentialList = await driver.getCredentials(); assert.equal(1, credentialList.length); let credential_id = credentialList[0].id(); let test_id = new Uint8Array([1, 2, 3, 4]); assert(arraysEqual(credential_id, test_id)); assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64')); }); it('Remove all credentials', async function() { await driver.addVirtualAuthenticator(options); let nonResidentCredential = new Credential().createNonResidentCredential( new Uint8Array([1, 2, 3, 4]), 'localhost', Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'), 0); await driver.addCredential(nonResidentCredential); await driver.removeAllCredentials(); let credentialList = await driver.getCredentials(); assert.equal(0, credentialList.length); }); it('Set is user verified', async function() { options.setIsUserVerified(true); assert.equal(options.getIsUserVerified(), true); }); });