Compare commits

..

2 Commits

Author SHA1 Message Date
e512edcde5 checkpoint 2024-05-02 13:32:22 -04:00
18507c7d79 idk 2024-05-02 12:25:29 -04:00

View File

@ -31,168 +31,275 @@ creates a new credential for it, and authenticates the credential.
This works with both FIDO 2.0 devices as well as with U2F devices. This works with both FIDO 2.0 devices as well as with U2F devices.
On Windows, the native WebAuthn API will be used. On Windows, the native WebAuthn API will be used.
""" """
import time
import fido2.webauthn
from fido2.hid import CtapHidDevice from fido2.hid import CtapHidDevice
from fido2.client import Fido2Client, WindowsClient, UserInteraction from fido2.client import Fido2Client, WindowsClient, UserInteraction
from fido2.server import Fido2Server from fido2.server import Fido2Server
from getpass import getpass from getpass import getpass
import sys import sys
import ctypes import ctypes
from fido2.ctap2 import Ctap2
REGISTER = False
gotAaguid = None
while True:
while True:
dev = next(CtapHidDevice.list_devices(), None)
if dev:
ctap2 = Ctap2(dev)
info = ctap2.get_info()
gotAaguid = info.aaguid
print(str(gotAaguid))
break
print("Waiting for device...")
time.sleep(0.1)
# Handle user interaction
class CliInteraction(UserInteraction):
def prompt_up(self):
print("\nTouch your authenticator device now...\n")
def request_pin(self, permissions, rd_id):
return getpass("Enter PIN: ")
def request_uv(self, permissions, rd_id):
print("User Verification required.")
return True
if REGISTER:
uv = "discouraged"
if WindowsClient.is_available() and not ctypes.windll.shell32.IsUserAnAdmin():
# Use the Windows WebAuthn API if available, and we're not running as admin
client = WindowsClient("https://example.com")
else:
# Locate a device
dev = next(CtapHidDevice.list_devices(), None)
if dev is not None:
print("Use USB HID channel.")
else:
try:
from fido2.pcsc import CtapPcscDevice
dev = next(CtapPcscDevice.list_devices(), None)
print("Use NFC channel.")
except Exception as e:
print("NFC channel search error:", e)
if not dev:
print("No FIDO device found")
sys.exit(1)
# Set up a FIDO 2 client using the origin https://example.com
client = Fido2Client(dev, "https://example.com", user_interaction=CliInteraction())
# Prefer UV if supported and configured
if client.info.options.get("uv") or client.info.options.get("pinUvAuthToken"):
uv = "preferred"
print("Authenticator supports User Verification")
# Handle user interaction server = Fido2Server({"id": "example.com", "name": "Example RP"}, attestation="direct")
class CliInteraction(UserInteraction):
def prompt_up(self):
print("\nTouch your authenticator device now...\n")
def request_pin(self, permissions, rd_id): user = {"id": b"user_id", "name": "A. User"}
return getpass("Enter PIN: ")
def request_uv(self, permissions, rd_id):
print("User Verification required.")
return True
uv = "discouraged" # Prepare parameters for makeCredential
create_options, state = server.register_begin(
user, user_verification=uv, authenticator_attachment="cross-platform"
)
# Create a credential
result = client.make_credential(create_options["publicKey"])
# Complete registration
auth_data = server.register_complete(
state, result.client_data, result.attestation_object
)
credentials = [auth_data.credential_data]
AAGUID = auth_data.credential_data.aaguid
cred_id = auth_data.credential_data.credential_id
pk_algo = auth_data.credential_data.public_key.ALGORITHM
pk_1 = auth_data.credential_data.public_key.get(1)
pk_3 = auth_data.credential_data.public_key.get(3)
pk__1 = auth_data.credential_data.public_key.get(-1)
pk__2 = auth_data.credential_data.public_key.get(-2)
pk__3 = auth_data.credential_data.public_key.get(-3)
import psycopg2
# Replace these variables with your connection parameters
dbname = "CNSA-276-FP-DAS"
user = "FP-DEV-USER"
password = "purchase-immortal-prescribe-repave-detention-seizing-candied-antiques-episode-list"
host = "postgres.eggtech.net"
# Function to connect to the PostgreSQL database and insert data
def insert_data(aaguid, cred_id, pk_algo, pk_1, pk_3, pk__1, pk__2, pk__3):
conn = None
try:
# Connect to the PostgreSQL server
conn = psycopg2.connect(dbname=dbname, user=user, password=password, host=host)
cur = conn.cursor()
# Define the SQL query for inserting data
insert_query = '''
INSERT INTO credential_data ("AAGUID", "credential_id", "pk_algo", "pk_1", "pk_3", "pk_neg1", "pk_neg2", "pk_neg3")
VALUES (%s, %s, %s, %s, %s, %s, %s, %s);
'''
# Execute the SQL query
cur.execute(insert_query, (aaguid, cred_id, pk_algo, pk_1, pk_3, pk__1, pk__2, pk__3))
# Commit the changes
conn.commit()
# Close communication with the database
cur.close()
except (Exception, psycopg2.DatabaseError) as error:
print(error)
finally:
if conn is not None:
conn.close()
# Assuming auth_data is defined and you've extracted your data as you've shown above
insert_data(
AAGUID,
cred_id,
pk_algo,
pk_1,
pk_3,
pk__1,
pk__2,
pk__3
)
print("New credential created!")
print("CLIENT DATA:", result.client_data)
print("ATTESTATION OBJECT:", result.attestation_object)
print()
print("CREDENTIAL DATA:", auth_data.credential_data)
if WindowsClient.is_available() and not ctypes.windll.shell32.IsUserAnAdmin():
# Use the Windows WebAuthn API if available, and we're not running as admin
client = WindowsClient("https://example.com")
else:
# Locate a device
dev = next(CtapHidDevice.list_devices(), None)
if dev is not None:
print("Use USB HID channel.")
else: else:
try: server = Fido2Server({"id": "example.com", "name": "Example RP"}, attestation="direct")
from fido2.pcsc import CtapPcscDevice uv = "discouraged"
dev = next(CtapPcscDevice.list_devices(), None) # Set up a FIDO 2 client using the origin https://example.com
print("Use NFC channel.") client = Fido2Client(dev, "https://example.com", user_interaction=CliInteraction())
except Exception as e:
print("NFC channel search error:", e)
if not dev: import psycopg2
print("No FIDO device found")
sys.exit(1)
# Set up a FIDO 2 client using the origin https://example.com # Replace these variables with your connection parameters
client = Fido2Client(dev, "https://example.com", user_interaction=CliInteraction()) dbname = "CNSA-276-FP-DAS"
user = "FP-DEV-USER"
password = "purchase-immortal-prescribe-repave-detention-seizing-candied-antiques-episode-list"
host = "postgres.eggtech.net"
# Prefer UV if supported and configured # Define the SQL query for retrieving data
if client.info.options.get("uv") or client.info.options.get("pinUvAuthToken"): select_query = '''
uv = "preferred" SELECT "AAGUID", credential_id, pk_algo, pk_1, pk_3, pk_neg1, pk_neg2, pk_neg3
print("Authenticator supports User Verification") FROM credential_data
WHERE "AAGUID" = %s;
server = Fido2Server({"id": "example.com", "name": "Example RP"}, attestation="direct")
user = {"id": b"user_id", "name": "A. User"}
# Prepare parameters for makeCredential
create_options, state = server.register_begin(
user, user_verification=uv, authenticator_attachment="cross-platform"
)
# Create a credential
result = client.make_credential(create_options["publicKey"])
# Complete registration
auth_data = server.register_complete(
state, result.client_data, result.attestation_object
)
credentials = [auth_data.credential_data]
AAGUID = auth_data.credential_data.aaguid
cred_id = auth_data.credential_data.credential_id
pk_algo = auth_data.credential_data.public_key.ALGORITHM
pk_1 = auth_data.credential_data.public_key.get(1)
pk_3 = auth_data.credential_data.public_key.get(3)
pk__1 = auth_data.credential_data.public_key.get(-1)
pk__2 = auth_data.credential_data.public_key.get(-2)
pk__3 = auth_data.credential_data.public_key.get(-3)
import psycopg2
# Replace these variables with your connection parameters
dbname = "CNSA-276-FP-DAS"
user = "FP-DEV-USER"
password = "purchase-immortal-prescribe-repave-detention-seizing-candied-antiques-episode-list"
host = "postgres.eggtech.net"
# Function to connect to the PostgreSQL database and insert data
def insert_data(aaguid, cred_id, pk_algo, pk_1, pk_3, pk__1, pk__2, pk__3):
conn = None
try:
# Connect to the PostgreSQL server
conn = psycopg2.connect(dbname=dbname, user=user, password=password, host=host)
cur = conn.cursor()
# Define the SQL query for inserting data
insert_query = '''
INSERT INTO credential_data ("AAGUID", "credential_id", "pk_algo", "pk_1", "pk_3", "pk_neg1", "pk_neg2", "pk_neg3")
VALUES (%s, %s, %s, %s, %s, %s, %s, %s);
''' '''
# Execute the SQL query
cur.execute(insert_query, (aaguid, cred_id, pk_algo, pk_1, pk_3, pk__1, pk__2, pk__3))
# Commit the changes # Function to connect to the PostgreSQL database and retrieve data
conn.commit() def fetch_data(aaguid):
conn = None
try:
# Connect to the PostgreSQL server
conn = psycopg2.connect(dbname=dbname, user=user, password=password, host=host)
cur = conn.cursor()
# Close communication with the database # Execute the SQL query
cur.close() cur.execute(select_query, (gotAaguid,))
except (Exception, psycopg2.DatabaseError) as error:
print(error)
finally:
if conn is not None:
conn.close()
# Assuming auth_data is defined and you've extracted your data as you've shown above # Fetch the results
insert_data( result = cur.fetchone()
AAGUID, if result:
cred_id, data = {
pk_algo, "AAGUID": result[0],
pk_1, "credential_id": result[1],
pk_3, "pk_algo": result[2],
pk__1, "pk_1": result[3],
pk__2, "pk_3": result[4],
pk__3 "pk_neg1": result[5],
) "pk_neg2": result[6],
"pk_neg3": result[7]
}
return data
else:
print("No data found for AAGUID:", aaguid)
return None
# Close communication with the database
cur.close()
except (Exception, psycopg2.DatabaseError) as error:
print(error)
finally:
if conn is not None:
conn.close()
# Example usage: Fetch data for a specific AAGUID and store in variables
aaguid_data = fetch_data("your_specific_aaguid_here")
print("New credential created!") if aaguid_data:
# Store each piece of data into a separate variable
testa = aaguid_data["AAGUID"]
cred_id = aaguid_data["credential_id"]
pk_algo = aaguid_data["pk_algo"]
pk_1 = aaguid_data["pk_1"]
pk_3 = aaguid_data["pk_3"]
pk_neg1 = aaguid_data["pk_neg1"]
pk_neg2 = aaguid_data["pk_neg2"]
pk_neg3 = aaguid_data["pk_neg3"]
auth_data = fido2.webauthn.AttestedCredentialData(testa, cred_id, pk_algo)
# auth_data.aaguid = AAGUID
# auth_data.credential_id = cred_id
# auth_data.public_key.ALGORITHM= pk_algo
# auth_data.public_key.setdefault(1, pk_1)
# auth_data.public_key.setdefault(3, pk_3)
# auth_data.public_key.setdefault(-1, pk__1)
# auth_data.public_key.setdefault(-2, pk__2)
# auth_data.public_key.setdefault(-3,pk__3)
print("CLIENT DATA:", result.client_data) credentials = [auth_data]
print("ATTESTATION OBJECT:", result.attestation_object)
print()
print("CREDENTIAL DATA:", auth_data.credential_data)
# Prepare parameters for getAssertion # Prepare parameters for getAssertion
request_options, state = server.authenticate_begin(credentials, user_verification=uv) request_options, state = server.authenticate_begin(credentials, user_verification=uv)
# Authenticate the credential # Authenticate the credential
result = client.get_assertion(request_options["publicKey"]) result = client.get_assertion(request_options["publicKey"])
# Only one cred in allowCredentials, only one response. # Only one cred in allowCredentials, only one response.
result = result.get_response(0) result = result.get_response(0)
# Complete authenticator # Complete authenticator
server.authenticate_complete( server.authenticate_complete(
state, state,
credentials, credentials,
result.credential_id, result.credential_id,
result.client_data, result.client_data,
result.authenticator_data, result.authenticator_data,
result.signature, result.signature,
) )
print("Credential authenticated!") print("Credential authenticated!")
print("CLIENT DATA:", result.client_data) print("CLIENT DATA:", result.client_data)
print() print()
print("AUTH DATA:", result.authenticator_data) print("AUTH DATA:", result.authenticator_data)