webauthn::WebAuthn method reg attestation_verify (public)
<instance of webauthn::WebAuthn> reg attestation_verify \ [ -st st ] [ -req req ]
Defined in packages/webauthn/tcl/webauthn-procs.tcl
- Switches:
- -st (optional)
- -req (optional)
- Testcases:
- No testcase defined.
Source code: set return_url [dict get $st return_url] set user_id [dict get $st user_id] if {![dict exists $req response clientDataJSON] || ![dict exists $req response attestationObject]} { throw {validation fields-missing} "missing required fields" } # ---- clientDataJSON :assert_clientdata_json -clientData_raw [dict get $req response clientDataJSON] -expected_type "webauthn.create" -expected_challenge [dict get $st challenge] -expected_origin [dict get $st origin] # ---- attestationObject (CBOR) -> authData -> credId + COSE_Key set attObj_b64u [dict get $req response attestationObject] set attObj_bin [ns_base64urldecode -binary -- $attObj_b64u] try { set ao [ns_cbor decode -binary -encoding binary $attObj_bin] } on error {e} { throw {validation attobj-cbor} "bad attestationObject CBOR: $e" } if {![dict exists $ao fmt] || ![dict exists $ao authData]} { throw {validation attobj-invalid} "attestationObject missing fmt/authData" } set fmt [dict get $ao fmt] if {$fmt ne "none"} { ns_log notice "registration attestation fmt=$fmt" } set authData [dict get $ao authData] if {[string length $authData] < 55} { throw {validation authdata-invalid} "authData too short" } set rpIdHash [string range $authData 0 31] :assert_rpidhash -rpIdHash $rpIdHash -rpId ${:rp_id} -context "attestation" binary scan [string range $authData 32 32] cu flags if {($flags & 0x40) == 0} { throw {validation attesteddata-missing} "no attested credential data" } binary scan [string range $authData 33 36] Iu signCount # fixed offsets from WebAuthn authData layout set aaguid [string range $authData 37 37+15] binary scan [string range $authData 53 53+1] S credIdLen if {$credIdLen <= 0 || (55+$credIdLen) > [string length $authData]} { throw {validation credidlen-invalid} "credentialId length out of range" } set credId [string range $authData 55 54+$credIdLen] set coseKey [string range $authData 55+$credIdLen end] try { set cose [ns_cbor decode -binary -encoding binary $coseKey] } on error {e} { throw {validation cose-cbor} "bad COSE_Key CBOR: $e" } # Basic COSE sanity (ES256 / P-256) if {![dict exists $cose 3] || [dict get $cose 3] != -7} { throw {validation alg-unsupported} "unsupported COSE alg (expected -7 ES256)" } if {![dict exists $cose 1] || [dict get $cose 1] != 2} { throw {validation keytype-unsupported} "unsupported COSE kty (expected 2 EC2)" } if {![dict exists $cose -1] || [dict get $cose -1] != 1} { throw {validation curve-unsupported} "unsupported COSE crv (expected 1 P-256)" } # Build DB values set credential_id [ns_base64urlencode -binary -- $credId] set public_key [dict create format cose fmt $fmt aaguid_b64u [ns_base64urlencode -binary -- $aaguid] alg [dict get $cose 3] crv [dict get $cose -1] cose_b64u [ns_base64urlencode -binary -- $coseKey] sign_count $signCount rp_id ${:rp_id}] return [dict create user_id $user_id return_url $return_url credential_id $credential_id public_key $public_key origin [dict get $st origin] sign_count $signCount]XQL Not present: Generic, PostgreSQL, Oracle
![[i]](/resources/acs-subsite/ZoomIn16.gif)